Aws-sdk-java: Deprecated Java 9 Javax Dependencies

Created on 29 Mar 2017  Â·  18Comments  Â·  Source: aws/aws-sdk-java

I'm using the S3 client and I get runtime exceptions on Java 9 regarding the deprecated usage of javax bind and activation classes. After adding the following API and implementation dependencies everything is working, but it would be nice to know exactly what versions should be used going forward.

investigating

Most helpful comment

I had same issue while migrating the code from java 8 to java 9, resolve with adding the module at run time
"--add-modules=java.xml.bind,java.activation".

Eg: java --add-modules=java.xml.bind,java.activation XmlTestClass

All 18 comments

@jamespedwards42 can you post the details of the RuntimeException you're getting? I'm not sure what you mean when you say you're adding the following implementations - I can't find any reference to com.sun.xml.bind or javax.activation in the codebase ..

@kiiadi Sorry, that was pretty vague of me. I'm adding those libraries as runtime dependencies so that those deprecated javax class files are available on the classpath. Here is the exception I get when calling AmazonS3#putObject. After adding those dependencies everything seems to be working fine.

Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
    at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1730)
    at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:3282)
    at Java9S3.main(Java9S3.java:19)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:552)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:186)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:476)
    ... 3 more

And here is the java version I ran it with:

â–¶ java -version
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+162-jigsaw-nightly-h6244-20170326)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+162-jigsaw-nightly-h6244-20170326, mixed mode)

@jamespedwards42 how are you resolving the dependencies? Are you using maven or something? What version of the SDK are you using?

Looks like our Base64 encoding implementation is the culprit - it uses https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/Base64.java#L19

I've had a bit of a look through the java 9 docs and it doesn't appear that these are deprecated:
http://download.java.net/java/jdk9/docs/api/javax/xml/bind/JAXBException.html

However you may need to add the java.xml.bind module

The entire java.xml.bind module is deprecated and marked as 'to be removed'. It is weird that they don't mark the individual classes within that module as deprecated. Not sure, maybe I'm misinterpreting it.

You also have to have the javax.activation dependency, without it I get the following exception. But it looks like the same issue with using the Base64 encoder.

For anyone wanting to get this working, they can add the dependencies I have listed above, and use the java.util.Base64.Encoder to provide the Base64 encoded MD5 checksum (ObjectMetadata#setContentMD5).

` Exception in thread "main" java.lang.NoClassDefFoundError: javax/activation/DataSource at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.<clinit>(RuntimeBuiltinLeafInfoImpl.java:478) at com.sun.xml.bind.v2.model.impl.RuntimeTypeInfoSetImpl.<init>(RuntimeTypeInfoSetImpl.java:63) at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:128) at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:84) at com.sun.xml.bind.v2.model.impl.ModelBuilder.<init>(ModelBuilder.java:162) at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.<init>(RuntimeModelBuilder.java:92) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:455) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:303) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:139) at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1156) at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:165) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:563) at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:290) at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:280) at javax.xml.bind.ContextFinder.find(ContextFinder.java:393) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:680) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:624) at com.amazonaws.util.Base64.<clinit>(Base64.java:44) at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1730) at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:3282) at Java9S3.main(Java9S3.java:19) Caused by: java.lang.ClassNotFoundException: javax.activation.DataSource at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:552) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:186) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:476) ... 24 more

Yeah looks like the same issue re: Base64, sounds good about using java.util.Base64.Encoder - and we'll definitely look to do this for our next major-version. However this only came in with Java 8 and the 1.11.x family of the SDK needs to support Java 6.

Thank you for your investigation and as I say, we'll remove the custom Base64 encoder in our next major version bump which will target Java 8 as the minimum version.

I'll close this for now.

@kiiadi Any possibility of using the Apache Commons Codec Base64 encoder so that Java 9 users don't have wait for the next major version for a proper fix? Or is the next major version just around the corner?

@jamespedwards42 we've got a couple of blog posts explaining the reasoning behind our custom implementation of Base64. The main reason not to use the Commons Codec version is because of performance - take a look:
https://aws.amazon.com/blogs/developer/a-fast-and-correct-base-64-codec/
https://aws.amazon.com/blogs/developer/follow-up-on-base64-codec-performance/

@kiiadi Oh! Even better! ... I didn't realize there was already a custom implementation provided. Is it unreasonable to simply drop the javax.xml.bind related classes and reduce com.amazonaws.util.Base64#encodeAsString to only use com.amazonaws.util.Base64Codec?

The issue still exists in the last version.

I had same issue while migrating the code from java 8 to java 9, resolve with adding the module at run time
"--add-modules=java.xml.bind,java.activation".

Eg: java --add-modules=java.xml.bind,java.activation XmlTestClass

@jayeshja, thanks for saving me time tracking down a workaround for this!

Hey guys!
Could you please tell me how it can be fixed if NoClassDefFoundError appears due to the class which is needed by maven publish plugin? I want to publish my jar into s3 bucket but have:

Exception in thread "pool-5-thread-1" java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter

I added dependencies mentioned above into buildscript section but that didn't help:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
        classpath group: 'com.sun.xml.bind', name: 'jaxb-core', version: '2.3.0'
        classpath group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.3.0'
        classpath group: 'javax.activation', name: 'activation', version: '1.1.1'
    }
}

ok, if anyone experience issue I described above you can specify in gradle.properties:

org.gradle.jvmargs=--add-modules=java.xml.bind,java.activation

even I am facing the same problem

For me the "Proper long-term solution: (All JDK versions)" from https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception-in-j worked fine, adding

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>

as explicit dependency in maven was enough

simply adding
compile group: 'javax.activation', name: 'activation', version: '1.1.1'
to build script fixed this issue for me

Was this page helpful?
0 / 5 - 0 ratings