-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Use context Classloader first if it is defined #255
Conversation
This PR was initally motivated by an issue where logback was unable to resolve a custom filter in a play 2.3 and 2.4 application in dev mode. The issue is that for all dependencies, including logback, the classes are loaded in a DependencyClassloader which is stable, while the project code is i loaded in a ReloadableClassloader which is a child of the stable class loader and is discarded whenever project source code changes. Since logback doesn't allow to pass a custom classloader, nor does it lookup the context classloader, it tries to resolve project classes in the stable classloader and fails to find project classes. This small change tries to use the context classloader first if it is set, and then falls back to the original behaviour. This effectively fixes the problem for play applications in dev mode.
a sample play 2.4 application demonstrating the issue is available at http://s000.tinyupload.com/index.php?file_id=23910239419295528828 simply change the version of logback to 1.1.2 or an unpatched 1.1.3 to get the error below and install a patched 1.1.3 to see it go away.
|
@jeantil What would happen, when ReloadableClassloader used to load that filter is discarded? As a workaround, can you just put that filter into DependencyClassloader? |
@panchenko I have not witnessed any adverse effect caused by a reload, even after forcing a full gc through jcmd. I would not expect Logback to be reinitialized. It would keep its reference to the old instance and work just fine albeit with the old behaviour. The only way I can think of for loading the filter in the DependencyClassLoader would be to package it in its own artifact and add a dependency on it. That's a lot of hassle for one 4 lines class, I did go through it for my current project but would much prefer if it could be reintegrated in the main project. Explaining why we had to create a separate artifact for that one class and documenting it for long term maintenance is not exactly foolproof :( |
This commit default to the TCL effectively changing logback behavior for all our users. It may be fine in your use case, but not for other users. There is a need for a more controlled way to set the class loader in effect. Sneaking in the TCL is certainly not the way go. |
Would you consider a PR that falls back to TCL if the class is not found using the current algorithm first ? |
This is still a huge problem, see playframework/playframework#8125. More than two years after this issue was opened it is still not possible to pass a custom classloader to logback, nor does it lookup the context classloader...
@panchenko @ceki What about that suggestion? Would that be ok for you? |
Passing custom class loader or using the TCCL is a rabbit hole I do not wish to descend into. As far as I am concerned, if the class loader that loaded logback cannot find a class, then tough luck. Resources are quite different because they don't have the class loader mismatch issue that classes have. |
I'm affected by this issue |
This PR was initally motivated by an issue where logback was unable to resolve a
custom filter in a play 2.3 and 2.4 application in dev mode.
The issue is that for all dependencies, including logback, the classes are
loaded in a DependencyClassloader which is stable, while the project code is i
loaded in a ReloadableClassloader which is a child of the stable class loader
and is discarded whenever project source code changes.
Since logback doesn't allow to pass a custom classloader, nor does it lookup the
context classloader, it tries to resolve project classes in the stable
classloader and fails to find project classes.
This small change tries to use the context classloader first if it is set, and
then falls back to the original behaviour. This effectively fixes the problem
for play applications in dev mode (tried using maven install and depending on the patched version locally)
More background on the classloader architecture in Play applications can be found in playframework/playframework#2847