Open RobertMolenda opened 2 years ago
I've looked into it and found out the following: First of all, the error only occurs if the dev-mode is enabled.
ElementTypesAreNonnullByDefault
) that are processed by the compiler.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.
See ticket # 28 for the fix-set and other feature implementations
where can I find that?
https://github.com/levigo/gwt-spring-boot-starter/issues/28 has the attached zip file of all the code/spring-stuff...
Got it, thanks, I'll take a look!
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.
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: @.***>
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.
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:
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.
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?
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.
If you find a solution feel free to open a PR
Adding GWT-Guava to the example project causes execution/debug failure in eclipse.
I simply added pom.xml
Application.gwt.xml
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: