vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
623 stars 167 forks source link

From 24.5, hotswap is generating a lot of error messages #20389

Open jorgheymans opened 3 weeks ago

jorgheymans commented 3 weeks ago

Description of the bug

Since upgrading to 24.5, when starting the application in debug mode with hotswap i get an endless stream of below log messages for various classes. On 24.4.x this is not happening. Is this a matter of silencing a log category or is this actually an issue? Using hotswap agent 2.0.0.

HOTSWAP AGENT: 13:37:33.332 ERROR (org.hotswap.agent.command.ReflectionCommand) - Error executin method onHotswap in class com.vaadin.flow.hotswap.Hotswapper
java.lang.reflect.InvocationTargetException
    at jdk.internal.reflect.GeneratedMethodAccessor139.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.hotswap.agent.command.ReflectionCommand.doExecuteReflectionCommand(ReflectionCommand.java:207)
    at org.hotswap.agent.command.ReflectionCommand.executeCommand(ReflectionCommand.java:168)
    at org.hotswap.agent.command.impl.CommandExecutor.run(CommandExecutor.java:43)
Caused by: java.lang.NoClassDefFoundError: javax/enterprise/util/AnnotationLiteral
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
    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:525)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:467)
    at com.vaadin.flow.hotswap.Hotswapper.resolveClass(Hotswapper.java:459)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
    at com.vaadin.flow.hotswap.Hotswapper.onHotswap(Hotswapper.java:148)
    ... 6 more
Caused by: java.lang.ClassNotFoundException: javax.enterprise.util.AnnotationLiteral
    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:525)

Expected behavior

No error messages

Minimal reproducible example

Use latest hotswap agent and start project in debug mode like usual.

Versions

Vaadin 24.5.2

mcollovati commented 3 weeks ago

It looks like Hotswap is notifying Flow about classes that are not available in its class loader. Definitely, javax/enterprise/util/AnnotationLiteral is incompatible with Vaadin 24, being on javax namespace.

I don't have idea where the agent is getting information about that classes, but at least you can restrict the Vaadin plugin to only react to changes in application classes by setting the vaadin.watched-packages in agent.properties file.

mcollovati commented 3 weeks ago

Anyway, such errors do not affect the application or the hotswap capabilities.

mcollovati commented 3 weeks ago

Documentation for vaadin.watched-packages is missing from the docs

jorgheymans commented 3 weeks ago

I don't have idea where the agent is getting information about that classes, but at least you can restrict the Vaadin plugin to only react to changes in application classes by setting the vaadin.watched-packages in agent.properties file.

Indeed, setting vaadin.watched-packages to my root application package in src/main/resources/hotswap-agent.properties makes the problem go away. Agreed that it does not affect the workings, but this is a mandatory setting then as the log flood is rather huge. Note i tested it on a basic Vaadin starter and there it does not happen ¯\_(ツ)_/¯

mcollovati commented 3 weeks ago

I wonder where the javax artifact comes from

jorgheymans commented 3 weeks ago

It's continuously logging the stacktrace but only for below 4 classes:

Caused by: java.lang.NoClassDefFoundError: io/undertow/server/handlers/resource/ResourceManager
Caused by: java.lang.NoClassDefFoundError: jakarta/enterprise/util/AnnotationLiteral
Caused by: java.lang.NoClassDefFoundError: javax/enterprise/util/AnnotationLiteral
Caused by: java.lang.NoClassDefFoundError: org/apache/deltaspike/core/api/config/view/metadata/ViewConfigResolver

None of these are a dependency in my project so it's really strange.

mshabarov commented 3 weeks ago

Could you please provide the dependency tree of your project? mvn dependency:tree

jorgheymans commented 3 weeks ago

tree.txt

jorgheymans commented 3 weeks ago

Maybe the hotswap agent itself has these dependencies via the plugin mechanism ?

HOTSWAP AGENT: 12:24:01.502 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent {2.0.0} - unlimited runtime class redefinition.
HOTSWAP AGENT: 12:24:02.233 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [WatchResources, ClassInitPlugin, AnonymousClassPatch, Hotswapper, JdkPlugin, Hibernate, HibernateJakarta, Hibernate3, Hibernate3JPA, Spring, SpringBoot, Jersey1, Jersey2, Jetty, Tomcat, ZK, Logback, Log4j2, MyFaces, Mojarra, Omnifaces, ELResolver, WildFlyELResolver, OsgiEquinox, Owb, OwbJakarta, Proxy, WebObjects, Weld, WeldJakarta, JBossModules, ResteasyRegistry, **Deltaspike, DeltaspikeJakarta,** GlassFish, Weblogic, Vaadin, Wicket, CxfJAXRS, FreeMarker, Undertow, MyBatis, MyBatisPlus, IBatis, JacksonPlugin, Idea, Thymeleaf, Velocity, Sponge]
jonas-tm commented 1 week ago

I am having the same issue when upgrading from 24.4 to 24.5

Vaadin 24.5.4 Spring Boot 3.3.5

Jetbrains JDK 21 with Hotswap installed -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar

HOTSWAP AGENT: 12:07:30.811 ERROR (org.hotswap.agent.command.ReflectionCommand) - Error executin method onHotswap in class com.vaadin.flow.hotswap.Hotswapper
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at org.hotswap.agent.command.ReflectionCommand.doExecuteReflectionCommand(ReflectionCommand.java:207)
    at org.hotswap.agent.command.ReflectionCommand.executeCommand(ReflectionCommand.java:168)
    at org.hotswap.agent.command.impl.CommandExecutor.run(CommandExecutor.java:43)
Caused by: java.lang.NoClassDefFoundError: io/undertow/server/handlers/resource/ResourceManager
    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.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:534)
    at java.base/java.lang.Class.forName(Class.java:513)
    at com.vaadin.flow.hotswap.Hotswapper.resolveClass(Hotswapper.java:470)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
    at com.vaadin.flow.hotswap.Hotswapper.onHotswap(Hotswapper.java:148)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    ... 4 more
Caused by: java.lang.ClassNotFoundException: io.undertow.server.handlers.resource.ResourceManager
    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)
    ... 26 more

HOTSWAP AGENT: 12:07:30.812 ERROR (org.hotswap.agent.command.ReflectionCommand) - Error executin method onHotswap in class com.vaadin.flow.hotswap.Hotswapper
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at org.hotswap.agent.command.ReflectionCommand.doExecuteReflectionCommand(ReflectionCommand.java:207)
    at org.hotswap.agent.command.ReflectionCommand.executeCommand(ReflectionCommand.java:168)
    at org.hotswap.agent.command.impl.CommandExecutor.run(CommandExecutor.java:43)
Caused by: java.lang.NoClassDefFoundError: jakarta/enterprise/util/AnnotationLiteral
    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.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:534)
    at java.base/java.lang.Class.forName(Class.java:513)
    at com.vaadin.flow.hotswap.Hotswapper.resolveClass(Hotswapper.java:470)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
    at com.vaadin.flow.hotswap.Hotswapper.onHotswap(Hotswapper.java:148)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    ... 4 more
Caused by: java.lang.ClassNotFoundException: jakarta.enterprise.util.AnnotationLiteral
    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)
    ... 26 more
mcollovati commented 1 week ago

Is the application executed as a fat-jar? ~Could you provide the output of a dependency tree for the application?~

At least, Vaadin does not have any dependency on undertow, so it would be good to know who is depending on it.

Edit: did not notice the tree was already provided

mcollovati commented 1 week ago

What makes me wonder is that if vaadin.watched-packages the not found classes should not be passed to Flow Hotswapper. My guess is that an application class is referencing directly or indirectly one of that classes, so when Flow Hotswapper tries to load the app class, it fails because of missing or referenced ones. Could you add an exception breakpoint in Hotswapper.resolveClass() and detect the main class that causes the error?

mcollovati commented 1 week ago

Anyway, it would be good to log the name of the class that cannot be resolved in Hotswapper.resolveClass()

jorgheymans commented 1 week ago

As far as i can see, putting a breakpoint in Hotswapper line 470, the classes that it continuously tries to load are these:

sun.security.ssl.AlpnExtension$AlpnSpec org.hotswap.agent.plugin.owb_jakarta.command.BeanClassRefreshAgent$1 org.hotswap.agent.plugin.undertow.PrefixingResourceManager org.hotswap.agent.plugin.deltaspike.jsf.ViewConfigResolverProxy

It was difficult to see which ones exactly are generating the stacktraces, but packages already seem similar (except for the AlpnExtension).

mcollovati commented 1 week ago

That's weird. If vaadin.watched-packages is set to only accept application packages, the listed classes should never reach Hotswapper because filtering happens in the agent plugin

mcollovati commented 1 week ago

To be honest, I don't know why agent classes are redefined. Also sun.security.ssl.AlpnExtension$AlpnSpec look very strange. What's the running environment? Spring boot app with embedded servlet container? Or WAR deployed to an external container?

jorgheymans commented 1 week ago

Note that in order to trigger the stacktraces again and see which classes are causing it, I had to remove the vaadin.watched-packages configuration again. With that config set to the root package of the application, the stacktraces are gone.

Environment is latest spring-boot with embedded tomcat.