Skip to content

Various complications with Java 13 #792

@firefligher

Description

@firefligher

Good evening/night (at least here in Germany 😁),

after a very long debugging session (started around 11:00 PM), I got your Maven plugin finally working together with Java 13 and succeeded building and running a simple app (empty Activity class). Since I thought that my approach may be useful for somebody else, I decided to document it here.

Disclaimer: Heavy patching of JAR files in your local Maven repository is required.
Also note: I used version 4.6.0 of this plugin and built an app with minimumSdkVersion = 26.

Fixing dex

I don't know, if this was the very first problem that I had, but it was one of the first: I needed to pass additional command-line arguments to dex as otherwise it would fail with the same issues as documented here. Aftwards the build section of my pom looked like this:

<build>
   <pluginManagement>
      <plugins>
         <plugin>
            <groupId>com.simpligility.maven.plugins</groupId>
            <artifactId>android-maven-plugin</artifactId>
            <version>4.6.0</version>
            <extensions>true</extensions>
         </plugin>
      </plugins>
   </pluginManagement>
   <plugins>
      <plugin>
         <groupId>com.simpligility.maven.plugins</groupId>
         <artifactId>android-maven-plugin</artifactId>
         <configuration>
            <sdk>
               <platform>26</platform>
            </sdk>
            <dex>
               <dexArguments>--min-sdk-version=26</dexArguments>
            </dex>
         </configuration>
      </plugin>
   </plugins>
</build>

Adding the XML serialization APIs as dependency

The next problem that occurred is pretty well-known to all developers that migrated from Java 8 to Java 9+: Oracle somehow modularized their platform, this broke a lot of dependencies. In this case, those were the XML serialzation APIs (as already documented here).

The simplest, but also quick-and-dirtiest, solution was to manually patch the pom.xml of your plugin inside my local Maven repository. (Of course, this is only possible after the plugin has been downloaded by Maven.)

In my case, I patched the file at HOME_DIR\.m2\repository\com\simpligility\maven\plugins\android-maven-plugin\4.6.0\android-maven-plugin-4.6.0.pom and the pom.xml that is stored inside the android-maven-plugin-4.6.0.jar (same directory). Both times I added the following lines to the dependencies-section:

<dependency>
   <groupId>javax.xml.bind</groupId>
   <artifactId>jaxb-api</artifactId>
   <version>2.3.1</version>
</dependency>
<dependency>
   <groupId>org.glassfish.jaxb</groupId>
   <artifactId>jaxb-runtime</artifactId>
   <version>2.3.2</version>
</dependency>

Afterwards, I recomputed the SHA1 checksums of both modified files and stored them in the corresponding .sha1 file (again, in the same directory).

Patching sdklib

After the last step, the next Maven execution resulted in a ClassNotFoundException that was not that easy to fix: The android-maven-plugin depends on the sdklib that is part of the AOSP. The plugin depends on the com.android.sdklib.internal.build.SignedJarBuilder class, which imports sun.* classes. Those classes are missing in the newer Java versions as already mentioned here. Unfortunately, I was not able to provide those sun-classes (pun not intended 😄) in an alternative way, because the Java compiler did not let me compile classes of the sun-package.

Thus, I decided to patch my local copy of sdklib and created a modified version of the SignedJarBuilder.java (diff only):

22,28d21
< import sun.misc.BASE64Encoder;
< import sun.security.pkcs.ContentInfo;
< import sun.security.pkcs.PKCS7;
< import sun.security.pkcs.SignerInfo;
< import sun.security.x509.AlgorithmId;
< import sun.security.x509.X500Name;
< 
107c100
<     private BASE64Encoder mBase64Encoder;
---
>     private java.util.Base64.Encoder mBase64Encoder;
177c170
<             mBase64Encoder = new BASE64Encoder();
---
>             mBase64Encoder = java.util.Base64.getEncoder();
330c323
<             attr.putValue(DIGEST_ATTR, mBase64Encoder.encode(mMessageDigest.digest()));
---
>             attr.putValue(DIGEST_ATTR, mBase64Encoder.encodeToString(mMessageDigest.digest()));
342c335
<         BASE64Encoder base64 = new BASE64Encoder();
---
>         java.util.Base64.Encoder base64 = java.util.Base64.getEncoder();
351c344
<         main.putValue(DIGEST_MANIFEST_ATTR, base64.encode(md.digest()));
---
>         main.putValue(DIGEST_MANIFEST_ATTR, base64.encodeToString(md.digest()));
364c357
<             sfAttr.putValue(DIGEST_ATTR, base64.encode(md.digest()));
---
>             sfAttr.putValue(DIGEST_ATTR, base64.encodeToString(md.digest()));
383a377
> 			/*
397a392
> 		*/

(NOTE: For some reason I used this file as base. (Fastest compatible Google result))

After compiling this class with javac, I patched the HOME_DIR\.m2\repository\com\android\tools\sdklib\25.3.0\sdklib-25.3.0.jar in my local Maven repository. Again, this also required replacing the existing SHA1 hash.

Manual signature

This time, Maven completed my build successfully. However installing the app on an Android phone did not work because Android noticed the missing signature (the previous file patch removed the signature logic). So, i tried to perform this step manually by entering these shell commands:

keytool -genkey -keyalg RSA -alias CERT -keystore myKeystore -validity 360
jarsigner -keystore myKeystore -verbose target\my.apk CERT

And it worked.

Additional notes:

I attempted to use d8 instead of dex, but the following configuration did not work:

<plugins>
   <plugin>
      <groupId>com.simpligility.maven.plugins</groupId>
      <artifactId>android-maven-plugin</artifactId>
      <configuration>
         <sdk>
            <platform>26</platform>
         </sdk>
         <dexCompiler>d8</dexCompiler>
         <d8>
            <minApi>26</minApi>
         </d8>
      </configuration>
   </plugin>
</plugins>

The Maven build process always ended with an exception because some command-line argument returned with a non-zero status code. I guess, there's something wrong with the command, but I'm too tired for further investigations...

Maybe I'm going to write a real patch for your project and create a pull request, if I have the time.

Cheers. (It took about 1h to collect and write down all the information 😄)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions