levigo / gwt-spring-boot-starter

A Spring-Boot Starter for Google Web Toolkit (GWT) applications
BSD 3-Clause "New" or "Revised" License
7 stars 6 forks source link

GWT-Guava - fails with java.lang.IllegalArgumentException: non-public interface is not defined by the given loader see ticket 28 for fixes #20

Open RobertMolenda opened 2 years ago

RobertMolenda commented 2 years ago

Adding GWT-Guava to the example project causes execution/debug failure in eclipse.

I simply added pom.xml

...
<!-- https://mvnrepository.com/artifact/com.google.guava/guava-gwt -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava-gwt</artifactId>
    <version>22.0</version>
</dependency>

Application.gwt.xml

<!-- Guava -->
<inherits name="com.google.common.collect.Collect" />

This is a JDK11 project so added '--add-opens java.base/jdk.internal.loader=ALL-UNNAMED' to the VM Parameters.

The project runs/debugs fine without the guava import. I've tried Guava versions 20.0 -> 22.0 and the 24.x-jre -> 31.1-jre versions with the same failure

Stack Trace:

2022-11-13 11:13:37.510 ERROR 1820 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.jadice.gwt.spring.devmode.DevModeLauncher': Invocation of init method failed; nested exception is java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: non-public interface is not defined by the given loader
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:767) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:719) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.23.jar:5.3.23]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.23.jar:5.3.23]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.5.jar:2.7.5]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.5.jar:2.7.5]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.5.jar:2.7.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.5.jar:2.7.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.5.jar:2.7.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.5.jar:2.7.5]
    at org.jadice.gwt.spring.demo.server.DemoApplication.main(DemoApplication.java:30) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.7.5.jar:2.7.5]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.jadice.gwt.spring.devmode.DevModeLauncher': Invocation of init method failed; nested exception is java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: non-public interface is not defined by the given loader
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1609) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1462) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:759) ~[spring-beans-5.3.23.jar:5.3.23]
    ... 25 common frames omitted
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: non-public interface is not defined by the given loader
    at org.jadice.gwt.spring.devmode.DevModeLauncher.launchDevMode(DevModeLauncher.java:326) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333) ~[spring-beans-5.3.23.jar:5.3.23]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157) ~[spring-beans-5.3.23.jar:5.3.23]
    ... 40 common frames omitted
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: non-public interface is not defined by the given loader
    at org.jadice.gwt.spring.devmode.CodeServerShutdownSupportingSuperDevListener.start(CodeServerShutdownSupportingSuperDevListener.java:117) ~[classes/:na]
    at org.jadice.gwt.spring.devmode.DevModeLauncher$SpringSupportDevMode.ensureCodeServerListener(DevModeLauncher.java:201) ~[classes/:na]
    at com.google.gwt.dev.DevModeBase.doStartup(DevModeBase.java:785) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.DevMode.doStartup(DevMode.java:551) ~[gwt-dev-2.9.0.jar:na]
    at org.jadice.gwt.spring.devmode.DevModeLauncher$SpringSupportDevMode.doStartup(DevModeLauncher.java:155) ~[classes/:na]
    at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:888) ~[gwt-dev-2.9.0.jar:na]
    at org.jadice.gwt.spring.devmode.DevModeLauncher$SpringSupportDevMode.start(DevModeLauncher.java:175) ~[classes/:na]
    at org.jadice.gwt.spring.devmode.DevModeLauncher.launchDevMode(DevModeLauncher.java:321) ~[classes/:na]
    ... 47 common frames omitted
Caused by: java.lang.IllegalArgumentException: non-public interface is not defined by the given loader
    at java.base/java.lang.reflect.Proxy$ProxyBuilder.mapToModule(Proxy.java:798) ~[na:na]
    at java.base/java.lang.reflect.Proxy$ProxyBuilder.<init>(Proxy.java:630) ~[na:na]
    at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:426) ~[na:na]
    at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329) ~[na:na]
    at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205) ~[na:na]
    at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:424) ~[na:na]
    at java.base/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1006) ~[na:na]
    at com.google.gwt.dev.javac.AnnotationProxyFactory.create(AnnotationProxyFactory.java:308) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.createAnnotation(CompilationUnitTypeOracleUpdater.java:545) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.resolveAnnotation(CompilationUnitTypeOracleUpdater.java:690) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.resolveAnnotations(CompilationUnitTypeOracleUpdater.java:704) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.resolveField(CompilationUnitTypeOracleUpdater.java:1054) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.resolveClass(CompilationUnitTypeOracleUpdater.java:955) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.access$700(CompilationUnitTypeOracleUpdater.java:82) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater$CompilationUnitTypeOracleResolver.resolveClass(CompilationUnitTypeOracleUpdater.java:187) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.asm.ResolveTypeSignature.visitClassType(ResolveTypeSignature.java:133) ~[gwt-dev-2.9.0.jar:na]
    at org.objectweb.asm.signature.SignatureReader.parseType(SignatureReader.java:220) ~[asm-7.1.jar:7.1]
    at org.objectweb.asm.signature.SignatureReader.accept(SignatureReader.java:122) ~[asm-7.1.jar:7.1]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.resolveClass(CompilationUnitTypeOracleUpdater.java:896) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.access$700(CompilationUnitTypeOracleUpdater.java:82) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater$CompilationUnitTypeOracleResolver.resolveClass(CompilationUnitTypeOracleUpdater.java:187) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.asm.ResolveTypeSignature.visitClassType(ResolveTypeSignature.java:133) ~[gwt-dev-2.9.0.jar:na]
    at org.objectweb.asm.signature.SignatureReader.parseType(SignatureReader.java:220) ~[asm-7.1.jar:7.1]
    at org.objectweb.asm.signature.SignatureReader.accept(SignatureReader.java:122) ~[asm-7.1.jar:7.1]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.resolveClass(CompilationUnitTypeOracleUpdater.java:896) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.addNewTypesDontIndex(CompilationUnitTypeOracleUpdater.java:415) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.addNewTypesDontIndex(CompilationUnitTypeOracleUpdater.java:493) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.addNewUnits(CompilationUnitTypeOracleUpdater.java:456) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationState.assimilateUnits(CompilationState.java:251) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationState.<init>(CompilationState.java:111) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationStateBuilder.doBuildFrom(CompilationStateBuilder.java:540) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.javac.CompilationStateBuilder.buildFrom(CompilationStateBuilder.java:464) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.cfg.ModuleDef.getCompilationState(ModuleDef.java:423) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.codeserver.Recompiler.initWithoutPrecompile(Recompiler.java:213) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.codeserver.Outbox.maybePrecompile(Outbox.java:89) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.codeserver.Outbox.<init>(Outbox.java:61) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.codeserver.CodeServer.makeOutboxTable(CodeServer.java:192) ~[gwt-dev-2.9.0.jar:na]
    at com.google.gwt.dev.codeserver.CodeServer.start(CodeServer.java:151) ~[gwt-dev-2.9.0.jar:na]
    at org.jadice.gwt.spring.devmode.CodeServerShutdownSupportingSuperDevListener.runCodeServer(CodeServerShutdownSupportingSuperDevListener.java:127) ~[classes/:na]
    at org.jadice.gwt.spring.devmode.CodeServerShutdownSupportingSuperDevListener.start(CodeServerShutdownSupportingSuperDevListener.java:113) ~[classes/:na]
    ... 54 common frames omitted
werthdavid commented 1 year ago

I've looked into it and found out the following: First of all, the error only occurs if the dev-mode is enabled.

Given that, I don't see any way how this could work at all as dev-mode starts a "code-server" that always has a different class-loader.

tl;dr; Guava-GWT seems not to be working with GWT and dev-mode at the same time, imho this is an issue of GWT and not gwt-spring-boot-starter. I'll close this, if somebody has an idea how it could be fix I can happily reopen the issue.

RobertMolenda commented 1 year ago

See ticket # 28 for the fix-set and other feature implementations

werthdavid commented 1 year ago

where can I find that?

RobertMolenda commented 1 year ago

https://github.com/levigo/gwt-spring-boot-starter/issues/28 has the attached zip file of all the code/spring-stuff...

werthdavid commented 1 year ago

Got it, thanks, I'll take a look!

sblommers commented 9 months ago

Hi all, I am having the exact same issue. Is there a way around this? This only seem to happen with gwt-spring-boot-starter, I have not seen this issue before when using gwt maven dev mode.

RobertMolenda commented 9 months ago

I ended up living / running off a customized local build - see https://github.com/levigo/gwt-spring-boot-starter/issues/28 for the zip file containing the code

On Fri, Feb 2, 2024 at 3:42 AM sblommers @.***> wrote:

Hi all, I am having the exact same issue. Is there a way around this? This only seem to happen with gwt-spring-boot-starter, I have not seen this issue before when using gwt maven dev mode.

— Reply to this email directly, view it on GitHub https://github.com/levigo/gwt-spring-boot-starter/issues/20#issuecomment-1923540664, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF4PC46P7ODZSPU5N6XHUWTYRS7HXAVCNFSM6AAAAAAR7DGTVCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMRTGU2DANRWGQ . You are receiving this because you authored the thread.Message ID: @.***>

sblommers commented 9 months ago

Hi @RobertMolenda thanks for your response. I tried your zip but immediately got other problems with the paths file:// is not allowed (new File throws an exception) so maybe something with urls not being correct in my situation. But I didn't see the error above. Sure this is about GWT-Guava and not something else?

Edit: yes I see that as soon as pulling in Guava-GWT it errors.

RobertMolenda commented 9 months ago

I can email you a current zip file of my working project, and as a final work around and just to get it going - I also removed all Guava from the UI side of the project - and have the following notes in my pom:

31.1-jre 31.1-jre On Fri, Feb 2, 2024 at 7:48 AM sblommers ***@***.***> wrote: > Hi @RobertMolenda thanks for your > response. I tried your zip but immediately got other problems with the > paths file:// is not allowed (new File throws an exception) so maybe > something with urls not being correct in my situation. But I didn't see the > error above. Sure this is about GWT-Guava and not something else? > > — > Reply to this email directly, view it on GitHub > , > or unsubscribe > > . > You are receiving this because you were mentioned.Message ID: > ***@***.***> >
sblommers commented 9 months ago

Hi @RobertMolenda thank you for helping out. I'm also removing Guava from UI side, this will take some time for us because we use it in around 20 different gwt modules. It would have been so sweet if it just worked but somehow GWT and Guava have forever been cursed.

sblommers commented 9 months ago

Hi @RobertMolenda it looks like I'm stuck again but now it seems with other libraries as well. I am sorry for asking are you willing to share your latest code with me? my email is blommers80@gmail.com?

sblommers commented 9 months ago

Hi @RobertMolenda @werthdavid I have been working on this issue the past two days and I can clearly see there is some problem with classloaders. My quess is that you should just use the class-loader that is currently being used and adapt that one to your needs. There is also the special RestartClassLoader from Spring, you can ignore that one by disabling devtools restart

public static void main(final String[] args) {
    System.setProperty("spring.devtools.restart.enabled", "false");
    SpringApplication.run(Application.class, args);
}

In DevModeLauncher I adapted the code for Java11 to be on the internal AppClassLoader by using the above statement. I then iterated the urls from that classloader and picked only those paths ending with WEB-INF/classes to get ../../../../src/main/java and addURL it to the classloader manually by using reflection, see this code:

if (stdClassLoader.getName().equals("app")) {
    Field field = stdClassLoader.getClass().getDeclaredField("ucp");
    field.setAccessible(true);
    Object ucp = field.get(stdClassLoader);
    final Method m = ucp.getClass().getDeclaredMethod("addURL", java.net.URL.class);
    for (URL sourcePath : sourcePaths) {
        try {
            m.invoke(ucp, sourcePath);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
}

And just after that using the known code and use the internal AppClassLoader of Java 11 and pass it along, not a new/custom classloader:

ClassLoader currentCCL = Thread.currentThread().getContextClassLoader();
try {
    devMode = new SpringSupportDevMode(sourcePaths, config);
    devMode.configure(getWarDirectory(), moduleNames);
    Thread.currentThread().setContextClassLoader(stdClassLoader);
    devMode.start();
} catch (Exception e) {
    LOGGER.error("Can't start DevMode", e);
    throw new RuntimeException(e);
} finally {
    Thread.currentThread().setContextClassLoader(currentCCL);
}

This situation can be adapted to all combinations of classloaders.

I'll try and make a usable codebase for the different scenarios. I am able to test for Java8 and Java11 at the moment with and without the RestartClassLoader. I still need to work on that. The question remains, what exactly do you need to add to the classloaders for good usage and debugging exactly. This above example is the minimum to at least get everything running and debugging in de current project without much trouble.

Thanks @RobertMolenda for your help to get a minimal version working with Guava and other stuff sensitive to being on different classloaders.

werthdavid commented 9 months ago

If you find a solution feel free to open a PR