Search code examples
javagradleproguardj2objc

j2objc not honoring dead code report


I am attempting to get j2objc to run on a few of my java only modules in a gradle project. I am using the gradle plugin for j2objc but I don't believe that is the source of any problems. The module uses XMLUnit to detect differences in input files. XMLUnit includes a class org.xmlunit.builder.JaxbBuilder which fails translation due to not seeing some javax classes which are omitted in j2objc, presumably because they fail to translate. In any case, my code does not use the JaxbBuilder class so I created a dead code report to omit it. I know I can use proguard to generate a more complete set but for now, my focus is just on preventing this class from being attempted as I am still working on a gradle CI pipeline for all this. The report is titled dead_code.log and contains only the following line:

org.xmlunit.builder.JaxbBuilder

The j2objc plugin configuration is specified as:

j2objcConfig {
    autoConfigureDeps true
    // Xcode workspace directory
    xcodeProjectDir '../ios'

    translateArgs '--dead-code-report', './dead_code.log'
    translateArgs '--doc-comments'
    translateArgs '-v'

    finalConfigure()          // Must be last call to configuration
}

And I can see in the log that the dead code arguments were added to the command line, but in execution I then see:

INEST: parsing jar:file:/Users/jenkins/.gradle/caches/modules-2/files-2.1/org.xmlunit/xmlunit-core/2.0.0-SNAPSHOT/b11b5e5d8e9f223af2fbaa93982d17b55899498/xmlunit-core-2.0.0-SNAPSHOT-sources.jar!org/xmlunit/builder/JaxbBuilder.java error: org/xmlunit/builder/JaxbBuilder.java:19: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:20: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:21: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:22: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:23: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:24: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:25: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:26: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:27: The import javax.xml.bind cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:31: The import java.beans.Introspector cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:43: Marshaller cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:56: Marshaller cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:57: Marshaller cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:82: Marshaller cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:83: The method createDefaultMarshaller() from the type JaxbBuilder refers to the missing type JAXBException error: org/xmlunit/builder/JaxbBuilder.java:87: JAXBSource cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:87: JAXBSource cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:87: Marshaller cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:92: JAXBException cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:93: DataBindingException cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:99: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:103: XmlRootElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:103: Bound mismatch: The generic method getAnnotation(Class) of type AnnotatedElement is not applicable for the arguments (Class). The inferred type XmlRootElement is not a valid substitute for the bounded parameter error: org/xmlunit/builder/JaxbBuilder.java:103: XmlRootElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:106: The method createJAXBElement(Object) from the type JaxbBuilder refers to the missing type JAXBElement error: org/xmlunit/builder/JaxbBuilder.java:108: The method createInferredJAXBElement(Object) from the type JaxbBuilder refers to the missing type JAXBElement error: org/xmlunit/builder/JaxbBuilder.java:117: JAXBException cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:117: PropertyException cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:118: JAXBContext cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:119: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:120: JAXBContext cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:120: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:120: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:123: JAXBContext cannot be resolved error: org/xmlunit/builder/JaxbBuilder.java:125: Marshaller cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:126: Marshaller cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:126: Marshaller cannot be resolved to a variable error: org/xmlunit/builder/JaxbBuilder.java:130: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:133: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:136: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:137: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:137: The method createJaxbElementFromObjectFactory(T) from the type JaxbBuilder refers to the missing type JAXBElement error: org/xmlunit/builder/JaxbBuilder.java:139: The method createInferredJAXBElement(T) from the type JaxbBuilder refers to the missing type JAXBElement error: org/xmlunit/builder/JaxbBuilder.java:146: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:156: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:161: JAXBElement cannot be resolved to a type error: org/xmlunit/builder/JaxbBuilder.java:174: Introspector cannot be resolved

Which I interpret to mean it tried to process the JaxbBuilder class. Is there something in the configuration that I am missing?


Solution

  • j2objc's first translation step is to invoke the Eclipse Java compiler, so dead code references need to be resolved for the translator to continue, even if the class with those references is later removed by the dead code elimination step. Adding a jar file to resolve the javax.xml.bind classes (like jaxb-api.jar) will clear up most of these errors.

    java.beans.Introspector remains an issue, though, as it's not part of the Android API and j2objc's JRE support is based on Android sources. Since this class and its references will be deleted, you can try specifying your JVM's rt.jar as the translator's bootclasspath (-Xbootclasspath: flag). Translation normally uses a jar that matches j2objc's JRE library, so unsupported classes are reported early. Specifying a JVM rt.jar as the bootclasspath defeats this error checking, but allows resolution of unsupported classes.

    Since the above sounds like a lot of work, another option you have is to request that the gradle plugin for j2objc have an exclude option, something like:

    j2objcConfig {
        ...
        translateArgs '-v'
        exclude 'org.xmlunit.builder.JaxbBuilder'
        ...
    

    The gradle plugin for j2objc team is separate from j2objc's, but they are very responsive to reasonable feature requests like this.