quarkus: Building a Quarkus application with Java 12+ can result in failure to start it in Java 8 runtime

Quarkus applications are generated to be runnable against a minimum Java 8 version. However, there appears to be an issue where if a Quarkus application is built using Java 8+ (especially Java 12 or higher) and then that application is started on Java 8, then it runs into an exception. One such exception is:

Exception in thread "main" java.lang.ExceptionInInitializerError
	at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:27)
Caused by: java.lang.RuntimeException: Failed to start quarkus
	at io.quarkus.runner.ApplicationImpl1.<clinit>(ApplicationImpl1.zig:325)
	... 1 more
Caused by: java.lang.NoClassDefFoundError: java/lang/constant/ConstantDesc
	at io.quarkus.arc.runtime.QuarkusConfigProducer_ProducerMethod_produceStringConfigProperty_75511873be6a3e578c4555b07b03c7231f99c7bc_Bean.<init>(QuarkusConfigProducer_ProducerMethod_produceStringConfigProperty_75511873be6a3e578c4555b07b03c7231f99c7bc_Bean.zig:257)
	at io.quarkus.arc.setup.Default_ComponentsProvider.getComponents(Default_ComponentsProvider.zig:81)
	at io.quarkus.arc.impl.ArcContainerImpl.<init>(ArcContainerImpl.java:102)
	at io.quarkus.arc.Arc.initialize(Arc.java:19)
	at io.quarkus.arc.runtime.ArcRecorder.getContainer(ArcRecorder.java:34)
	at io.quarkus.deployment.steps.ArcProcessor$generateResources15.deploy_0(ArcProcessor$generateResources15.zig:72)
	at io.quarkus.deployment.steps.ArcProcessor$generateResources15.deploy(ArcProcessor$generateResources15.zig:36)
	at io.quarkus.runner.ApplicationImpl1.<clinit>(ApplicationImpl1.zig:295)
	... 1 more
Caused by: java.lang.ClassNotFoundException: java.lang.constant.ConstantDesc
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 9 more

It looks like we are missing the use of -release option that should be configured in our Maven (and Gradle?) compiler plugins to prevent javac from using Java 8+ APIs in the generated class files.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 33 (33 by maintainers)

Commits related to this issue

Most upvoted comments

Agreed, I did that in #6517

I think we should just hard code restrictions around the problematic interfaces. Enough people seem to be affected by this that it is worth doing.

I think Quarkus should not blindly register the types from hierarchy of bean type at compile time unless such types are actually used (at injection points for example, etc.) in the app. Only in that case would Quarkus built artifacts have binary compatibility that is normally expected in a Java app. So what do you think?

I am not a CDI expert, but I don’t think we can impose such a restriction because of the fact that one can use Arc.container().instance(...) to get beans at runtime without there being an injection point.

What I propose we do for now, is that we just hard-code an exclusion for the two problematic interfaces (which are used by String in Java 12+) in the Arc code (I made a small modification to Arc to do this and it does fix the reported problem). Of course it will mean that users won’t be able to inject ConstantDesc and Constable but I don’t think that will be such a common case anyway… What you folks are reporting is a much more common case and that is the one I think we need to address.

WDYT @mkouba @stuartwdouglas ?

@Sanne @Produces is mandatory 😉.