Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite stream of hotswapping events #589

Closed
Artur- opened this issue Sep 18, 2024 · 13 comments
Closed

Infinite stream of hotswapping events #589

Artur- opened this issue Sep 18, 2024 · 13 comments

Comments

@Artur-
Copy link
Contributor

Artur- commented Sep 18, 2024

When using the Vaadin plugin in 2.0.0, I every now and then see an infinite stream of hotswapping events for the same class being sent to Hotswapper.onHotswap. Today it looks like

Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]
Hotswapping[com.github.javaparser.resolution.declarations.AssociableToAST]

and it continues forever. Would this be a problem in the Vaadin plugin, HotswapAgent or JBR?

The stack trace in IntelliJ does not really tell that much
image

@Artur-
Copy link
Contributor Author

Artur- commented Sep 18, 2024

With trace logging enabled for HA, I see

HOTSWAP AGENT: 10:37:05.105 DEBUG (org.hotswap.agent.command.impl.SchedulerImpl) - Executing Command{class='com.vaadin.flow.hotswap.Hotswapper', methodName='onHotswap'}
HOTSWAP AGENT: 10:37:05.105 TRACE (org.hotswap.agent.command.impl.CommandExecutor) - Executing command Command{class='com.vaadin.flow.hotswap.Hotswapper', methodName='onHotswap'}
HOTSWAP AGENT: 10:37:05.106 TRACE (org.hotswap.agent.command.ReflectionCommand) - Executing command: requestedClassLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@27ddd392, resolvedClassLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@27ddd392, class=class com.vaadin.flow.hotswap.Hotswapper, method=onHotswap, params=[[Ljava.lang.String;@669856bd, false]
Hotswapping[com.vaadin.flow.component.dependency.StyleSheet]
HOTSWAP AGENT: 10:37:05.208 DEBUG (org.hotswap.agent.command.impl.SchedulerImpl) - Executing Command{class='com.vaadin.flow.hotswap.Hotswapper', methodName='onHotswap'}
HOTSWAP AGENT: 10:37:05.208 TRACE (org.hotswap.agent.command.impl.CommandExecutor) - Executing command Command{class='com.vaadin.flow.hotswap.Hotswapper', methodName='onHotswap'}
HOTSWAP AGENT: 10:37:05.208 TRACE (org.hotswap.agent.command.ReflectionCommand) - Executing command: requestedClassLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@27ddd392, resolvedClassLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@27ddd392, class=class com.vaadin.flow.hotswap.Hotswapper, method=onHotswap, params=[[Ljava.lang.String;@669856bd, false]
Hotswapping[com.vaadin.flow.component.dependency.StyleSheet]
HOTSWAP AGENT: 10:37:05.313 DEBUG (org.hotswap.agent.command.impl.SchedulerImpl) - Executing Command{class='com.vaadin.flow.hotswap.Hotswapper', methodName='onHotswap'}
HOTSWAP AGENT: 10:37:05.313 TRACE (org.hotswap.agent.command.impl.CommandExecutor) - Executing command Command{class='com.vaadin.flow.hotswap.Hotswapper', methodName='onHotswap'}
HOTSWAP AGENT: 10:37:05.313 TRACE (org.hotswap.agent.command.ReflectionCommand) - Executing command: requestedClassLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@27ddd392, resolvedClassLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@27ddd392, class=class com.vaadin.flow.hotswap.Hotswapper, method=onHotswap, params=[[Ljava.lang.String;@669856bd, false]
Hotswapping[com.vaadin.flow.component.dependency.StyleSheet]

@skybber
Copy link
Contributor

skybber commented Sep 18, 2024

Could you check please from which method SchedulerImpl.scheduleCommand() is called?

@Artur-
Copy link
Contributor Author

Artur- commented Sep 18, 2024

It originates here

ReflectionCommand command = new ReflectionCommand(vaadinHotswapperObj,
"onHotswap", new String[]{className},
event == REDEFINE);
scheduler.scheduleCommand(command, reloadQuietTime);

@Artur-
Copy link
Contributor Author

Artur- commented Sep 18, 2024

But the Reloading class {} because of {}" is not constantly logged, so it would seem that scheduleCommand is only called once

@Artur-
Copy link
Contributor Author

Artur- commented Sep 18, 2024

There are a lot of commands "running"
Screenshot 2024-09-18 at 14 03 34

and in SchedulerImpl.finished() some gets removed from runningCommands but then when onHotswap is called again, scheduledCommands contain the same commands (in this case it is two, apparently it can also be one) and the ones in runningCommands also seem to remain

@skybber
Copy link
Contributor

skybber commented Sep 18, 2024

  • Are you sure you need process LoadEvent.DEFINE as redefine event in Vaadin Hotswapper?:
@OnClassLoadEvent(classNameRegexp = ".*", events = {LoadEvent.DEFINE, LoadEvent.REDEFINE})
  • commands should be remove by it.remove(); in SchedulerImpl

@Artur-
Copy link
Contributor Author

Artur- commented Sep 18, 2024

The problem is that it.remove() does not remove the command. Also when debugging I can see that after

            for (Iterator<Map.Entry<Command, DuplicateScheduleConfig>> it = scheduledCommands.entrySet().iterator(); it.hasNext(); ) {
                Map.Entry<Command, DuplicateScheduleConfig> entry = it.next();

then
scheduledCommands.containsKey(entry.getKey()) is false, or in other words scheduledCommands.containsKey(scheduledCommands.entrySet().iterator().next().getKey()) is false. This seems like the hash code of ReflectionCommand could change after adding the command to the map or something similar

@Artur-
Copy link
Contributor Author

Artur- commented Sep 18, 2024

It can, because ReflectionCommand.getTargetClassLoader() modifies the targetClassLoader field when it is null, and after that, the hash code no longer matches

@skybber
Copy link
Contributor

skybber commented Sep 18, 2024

It looks like a bug. I suggest making all attributes in the ReflectionCommand class final and initializing them in the constructor.

@skybber skybber reopened this Sep 18, 2024
@skybber
Copy link
Contributor

skybber commented Sep 18, 2024

A new fixed version is available at:

https://github.com/HotswapProjects/HotswapAgent/releases/tag/2.0.1-SNAPSHOT

Could you please check if it resolves your issue?

@Artur-
Copy link
Contributor Author

Artur- commented Sep 19, 2024

Thanks! I think it resolves the issue but as it is a timing issue, I cannot say for sure

MarcinVaadin pushed a commit to vaadin/intellij-plugin that referenced this issue Sep 19, 2024
@Artur-
Copy link
Contributor Author

Artur- commented Sep 19, 2024

Haven't seen it again so far

@Artur- Artur- closed this as completed Sep 19, 2024
@skybber
Copy link
Contributor

skybber commented Sep 23, 2024

Problem is fixed in version 2.0.1 , is is released on maven https://mvnrepository.com/artifact/org.hotswapagent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants