ClassNotFoundException when using quarkus:dev
See original GitHub issueHello @quarkus Team 😃
I have a multimodule project with one of modules being an example subproject which exposes very simple REST API. Everything works fine when I start this example with a runner:
java -jar target/abberwoult-example-0.0.1-SNAPSHOT-runner.jar -cp target/lib/*
The resource is started and I can access REST API. This is ok but takes some time, so I wanted to use mvn quarkus:dev. I see that support for But when I try to run my example with a dev mojo, that is:quarkus:dev in multimodule projects was introduced by https://github.com/quarkusio/quarkus/pull/1973 and thus should be working fine,
$ cd abberwoult-example
$ mvn quarkus:dev
I’m getting the following error:
18:12:22,936 ERROR [io.qua.dev.DevModeMain] Failed to start quarkus: java.lang.ExceptionInInitializerError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:129)
at io.quarkus.dev.DevModeMain.doStart(DevModeMain.java:173)
at io.quarkus.dev.DevModeMain.main(DevModeMain.java:100)
Caused by: java.lang.RuntimeException: Failed to start quarkus
at io.quarkus.runner.ApplicationImpl1.<clinit>(Unknown Source)
... 8 more
Caused by: java.lang.IllegalStateException: Cannot load com.example.FruitRepositoryActor
at com.github.sarxos.abberwoult.deployment.ActorInterceptorRegistryTemplate.register(ActorInterceptorRegistryTemplate.java:25)
at io.quarkus.deployment.steps.AbberwoultProcessor$doRegisterActors9.deploy_0(Unknown Source)
at io.quarkus.deployment.steps.AbberwoultProcessor$doRegisterActors9.deploy(Unknown Source)
at io.quarkus.runner.ApplicationImpl1.<clinit>(Unknown Source)
... 8 more
Caused by: java.lang.ClassNotFoundException: com.example.FruitRepositoryActor
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
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)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.github.sarxos.abberwoult.deployment.ActorInterceptorRegistryTemplate.register(ActorInterceptorRegistryTemplate.java:23)
... 11 more
This error comes from a @Template annotated class which is pretty simple:
@Template
public class ActorInterceptorRegistryTemplate {
private static final Logger LOG = LoggerFactory.getLogger(ActorInterceptorRegistry.class);
public void register(final String className) {
final Class<?> clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Cannot load " + className, e);
}
LOG.debug("Loaded {}", clazz);
ActorInterceptorRegistry.registerReceiversFrom(clazz);
ActorInterceptorRegistry.registerPreStartsFrom(clazz);
ActorInterceptorRegistry.registerPostStopsFrom(clazz);
}
}
I was able to w/a this by implementing custom class loader which loads classes directly from a known location, but some other issue (class not found exception, again) appeared which is probably linked to the same problem but is thrown from a synthetic beans so I gave up in digging more.
This is my custom class loader I implemented to (partially) workaround described problem:
public static class CustomClassLoader extends ClassLoader {
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
final byte[] b = loadClassFromFile(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassFromFile(final String className) throws ClassNotFoundException {
LOG.debug("Loading class {}", className);
final String resourcePath = className.replace('.', File.separatorChar) + ".class";
int value = 0;
try (
final InputStream is = new FileInputStream(resourcePath);
final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
while ((value = is.read()) != -1) {
baos.write(value);
}
return baos.toByteArray();
} catch (FileNotFoundException e) {
throw new ClassNotFoundException("Cannot find resource " + resourcePath, e);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
To reproduce:
$ git clone git@github.com:sarxos/abberwoult.git
$ cd abberwoult
$ mvn clean install -DskipTests
$ cd abberwoult-example
$ mvn quarkus:dev
Issue Analytics
- State:
- Created 4 years ago
- Reactions:4
- Comments:13 (11 by maintainers)
Top Related StackOverflow Question
I’m having a similar problem. I’m using a specific class to use on the camel-core component. When I run it works, when I run in dev mode I get a
ClassNotFoundExceptionatat io.quarkus.camel.core.deployment.CamelInitProcessor.visitService(CamelInitProcessor.java:154)I’m wondering why that works not on dev mode, is it usingcamel-coreinstead ofquarkus-camel-core. How would that make a difference to the classpath?Additionally, I debugged this and on the classloading step I tried to load other classes from my project and they were not loaded as well. I’m guessing that at that step we don’t have the classes of the project available.
I could w/a this but is it intended for the classloading happen at a point where the project classes are not in there?
#TODO: Quakrus Testing framework uses QuarkusClassLoader, for workaround use this below property in test/app.properties quarkus.test.flat-class-path=true