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

How to avoid duplicate class warnings? #3190

Closed
Spring3Coke opened this issue Dec 6, 2018 · 4 comments
Closed

How to avoid duplicate class warnings? #3190

Spring3Coke opened this issue Dec 6, 2018 · 4 comments

Comments

@Spring3Coke
Copy link

Hello. When I use jetty9.3.5, if there is servlet-api.jar in the project, then starting the jetty container will not report Warn :scanned from multiple locations: jar: . But when I use the jetty 9.4.14 version, starting jetty will report Warn:scanned from multiple locations: jar: . So, I would like to ask, is there a scan warning action in the Jetty 9.3.5 version, and then done in jetty 9.4.14? Or how can I avoid this warning not being reported in the Jetty 9.4.14 release? Thank you

@joakime
Copy link
Contributor

joakime commented Dec 6, 2018

Jetty added the warning for duplicate scanned classes due to Issue #1819.
Which first showed up in Jetty 9.4.8.

Subsequent improvements to the warning have been made, most notably from Issue #2043
Which made it into Jetty 9.4.9

There has been no work for either of those issues in Jetty 9.3.x

This warning tells you an important detail, you have duplicate classes in your running server / application!

Why is this important? well, the biggest concern is that you have no guarantee of consistent behavior between runs.
This is because a ClassLoader has no order requirements, or expectations, this run its A.jar:B.jar:C.jar, next run its C.jar:A.jar:B.jar etc...

Only the first class encountered will be used by ClassLoader, so if you have version 2.0 and 3.0 in your ClassLoader, sometimes you'll get new functionality, sometimes you'll get old functionality. It's completely the luck of the draw.

How do you avoid this being reported?
Fix your Classpath, start with those entries that are reported from your <my.app.name>.war file (the WEB-INF/classes and WEB-INF/lib/*.jar entries)
Then, if there's more, fix your Server Classpath.
If you are using Jetty's ${jetty.base} and ${jetty.home} you shouldn't be seeing these duplicates from the Server classpath.

If you are using jetty-maven-plugin, then you are in development mode, and shouldn't be running in production anyway.
(But you can still fix this within your project's dependencies)

@joakime joakime changed the title jetty container version upgrade How to avoid duplicate class warnings? Dec 6, 2018
@Spring3Coke
Copy link
Author

Thank you very much!
Then I have a scenario: First I introduced a jar package, but a class in the jar package can't satisfy me, so I rewrote the class in my own project, which led us to The path of the class is the same as the path in the JAR package. When jetty starts, it will report
com..server.JettyServer scanned from multiple locations: jar:
File: .../WEB-INF/lib/
.jar!/com/je/server/JettyServer.class,
File: ...webapp/WEB-INF/classes/com/je/server/JettyServer.class.
Here, it actually loads the JettyServer class that was rewritten in my project first, so is the warning here not supposed to be there?

@joakime
Copy link
Contributor

joakime commented Dec 6, 2018

From the point of view of Java, that class exists in two places.

Once from WEB-INF/classes, and again from WEB-INF/lib/***.jar.
The ClassLoader for your webapp (when asked to load that class) can load either of those, depends entirely on luck and is random.

In the past (around 1998), this wasn't a big deal, but as webapps and the technology evolves (such as annotations and bytecode scanning), this becomes important to warn about and highlight in log warning messages.
Java 9+ makes this even more important to address, as the internals of Java ClassLoaders has changed again. (If you don't follow the old school rules of ClassLoaders, you will be bit even faster)
Technologies like JPMS (built into JVM from Java 9+) makes duplicate classes in multiple locations even more of a problem (and in many cases the JVM will refuse to start if this is true).
It's very easy to see a future (in about 3 years time) where duplicate classes in multiple locations on a ClassLoader is just outright banned by the JVM itself.

@janbartel
Copy link
Contributor

I'm closing this issue, as the solution is to ensure that each class is only on the classpath once.

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

3 participants