Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassNotFoundException when running in a JIB image #4328

Open
skin27 opened this issue Oct 23, 2024 · 1 comment
Open

ClassNotFoundException when running in a JIB image #4328

skin27 opened this issue Oct 23, 2024 · 1 comment

Comments

@skin27
Copy link

skin27 commented Oct 23, 2024

Environment:

Jib version: 3.4.4
Build tool: Gradle (8.10.2)
OS: Mac

Description of the issue:

If have a Spring Boot application to uses Angus mail (Jakarta mail). When I run it locally, directly from gradle, it works as expected. However when I use JIB and run it in a docker container I get the following error:

java.lang.NoClassDefFoundError: javax/activation/DataContentHandler
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at jakarta.activation.MailcapCommandMap.getDataContentHandler(MailcapCommandMap.java:594)
	at jakarta.activation.MailcapCommandMap.createDataContentHandler(MailcapCommandMap.java:572)
	at jakarta.activation.CommandMap.createDataContentHandler(CommandMap.java:205)
	at jakarta.activation.DataHandler.getDataContentHandler(DataHandler.java:587)
	at jakarta.activation.DataHandler.getContent(DataHandler.java:514)
	at jakarta.mail.internet.MimeMessage.getContent(MimeMessage.java:1504)
	at org.assimbly.mail.component.mail.MailBinding.extractBodyFromMail(MailBinding.java:302)
	at org.assimbly.mail.component.mail.MailMessage.createBody(MailMessage.java:93)
	at org.apache.camel.support.MessageSupport.getBody(MessageSupport.java:68)
	at org.assimbly.mail.component.mail.MailConsumer.createExchange(MailConsumer.java:406)
	at org.assimbly.mail.component.mail.MailConsumer.retrieveMessages(MailConsumer.java:328)
	at org.assimbly.mail.component.mail.MailConsumer.poll(MailConsumer.java:164)
	at org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:205)
	at org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:119)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
	at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.lang.ClassNotFoundException: javax.activation.DataContentHandler
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	... 38 common frames omitted

My JIB configuration:

jib {
    from {
        image = 'container-registry.oracle.com/graalvm/jdk:21'
    }
    to {
        image = 'assimbly/gateway-full'
    }
    container {
        ports = ['1000', '1616','1617', '2000-2003/udp', '8088', '8443', '61616','61617','9000','9001']
        format = 'OCI'
    }
    containerizingMode = 'exploded'
    extraDirectories {
        paths {
            path {
                // copies the contents of 'src/main/jib' into '/' on the container
                from = file('src/main/jib')
            }
            path {
                // copies the contents of 'src/main/another/dir' into '/extras' on the container
                from = file('src/main/data')
                into = '/data'
            }
        }
        permissions = [
            '/entrypoint.sh': '755',
            '/data/**': '775',
            '/data/**/*': '775',
        ]
    }

}

My EntryEndpoint.sh:

exec java ${JAVA_OPTS} -cp /app/resources/:/app/classes/:/app/libs/* "org.assimbly.gateway.GatewayApp"

Looking at the created image, everything seems to build well. I checked the lib directory on the container and all expect jar files are there (no duplicates or old javax jar).

We ran most integration tests, but the above one, was the only that failed. The same error occured with the GraalVM image and Amazon Corretto image. We also tried to force the Java dependencies, but that made no difference. Also I doubt why it's needed, because locally it works as expected.

What could be different that it works locally, but doesn't work in the image build jib?

@skin27
Copy link
Author

skin27 commented Oct 24, 2024

I was wondering if maybe this issue is also related:

https://stackoverflow.com/questions/53635602/java-classpath-ordering-inconsistent-between-docker-hosts

This basically says that when the "/app/libs/*" used with a wildcard you may not have consistent. I try also to use containerizedMode=packaged. But then it's not very clear where the jar file is placed and what the correct entry endpoint should be.

I did copy a fat jar (both directly with a dockerfile and with jib extraDirectories) to the image, based on this answer:

https://stackoverflow.com/questions/64849472/build-spring-boot-fat-jar-using-jib

And then it worked. It's however unclear if fatjars are supported by jib.

To summarize:

  1. Exploded --> Does not work
  2. Packaged --> Works
  3. FatJar --> Works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants
@lqiu96 @skin27 and others