oblac / jodd

Jodd! Lightweight. Java. Zero dependencies. Use what you like.
https://jodd.org
BSD 2-Clause "Simplified" License
4.06k stars 724 forks source link

java 9 class files in jode-core and tomee 1.7.x #567

Closed moh-sushi closed 6 years ago

moh-sushi commented 6 years ago

Hi,

i have found an "issue" while using current jodd version 4.1.1 in apache tomee 1.7.4 .

Apache TomEE 1.7.4 and its bundled asm 5 try to read the java 9 class files under jodd-core/META-INF/versions. This fails because asm5 can not read java 9 class files. (see https://github.com/moh-sushi/tomee-and-jodd)

my question: It is possible to offer an extra jodd-core-artefact jodd-core-jre8.jar? This new artefact is the same as the original jodd-core artefact but without any java 9 class files under META-INF/versions.

This new artefact may be removed in future if using java 8 is outdated.

my workaround for now is to remove these class files from jodd-core artefact and re-upload it onto our artefact manager.

Thx!

yujinping commented 6 years ago

Ops. I have the same problem! Environment: jdk 8 jetty 9.3 jetty-runner

the trace info:


23:27:08.297 INFO  org.eclipse.jetty.util.log - Logging initialized @1496ms
23:27:08.354 INFO  org.eclipse.jetty.runner.Runner - Runner
23:27:08.723 INFO  org.eclipse.jetty.server.Server - jetty-9.3.21.v20170918
23:27:10.585 INFO  org.eclipse.jetty.annotations.AnnotationConfiguration - Scanning elapsed time=1091ms
23:27:10.585 WARN  org.eclipse.jetty.webapp.WebAppContext - Failed startup of context o.e.j.w.WebAppContext@51e5fc98{/,file:///D:/MyProjects/java/demo/jodd41/web/,UNAVAILABLE}{file:///D:/MyProjects/java/demo/jodd41/web/}
org.eclipse.jetty.util.MultiException: Multiple exceptions
    at org.eclipse.jetty.annotations.AnnotationConfiguration.scanForAnnotations(AnnotationConfiguration.java:534) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationConfiguration.configure(AnnotationConfiguration.java:447) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.webapp.WebAppContext.configure(WebAppContext.java:496) ~[jetty-webapp-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1363) ~[jetty-webapp-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778) ~[jetty-server-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262) ~[jetty-servlet-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:522) [jetty-webapp-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) [jetty-server-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:161) [jetty-server-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) [jetty-server-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.server.Server.start(Server.java:422) [jetty-server-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:105) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) [jetty-server-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.server.Server.doStart(Server.java:389) [jetty-server-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) [jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.runner.Runner.run(Runner.java:518) [jetty-runner-9.4.6.v20170531.jar:9.4.6.v20170531]
    at org.eclipse.jetty.runner.Runner.main(Runner.java:559) [jetty-runner-9.4.6.v20170531.jar:9.4.6.v20170531]
Caused by: org.eclipse.jetty.util.MultiException: Multiple exceptions
    at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:893) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationParser.parse(AnnotationParser.java:851) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationConfiguration$ParserTask.call(AnnotationConfiguration.java:163) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationConfiguration$1.run(AnnotationConfiguration.java:546) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at java.lang.Thread.run(Thread.java:748) ~[?:1.8.0_152]
    Suppressed: java.lang.RuntimeException: Error scanning entry META-INF/versions/9/jodd/util/UnsafeInternal.class from jar file:///D:/MyProjects/java/demo/jodd41/web/WEB-INF/lib/jodd-all-4.1.1.jar
        at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:906) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationParser.parse(AnnotationParser.java:851) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationConfiguration$ParserTask.call(AnnotationConfiguration.java:163) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationConfiguration$1.run(AnnotationConfiguration.java:546) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
        at java.lang.Thread.run(Thread.java:748) ~[?:1.8.0_152]
    Caused by: java.lang.IllegalArgumentException
        at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
        at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
        at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
        at org.eclipse.jetty.annotations.AnnotationParser.scanClass(AnnotationParser.java:977) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationParser.parseJarEntry(AnnotationParser.java:958) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:902) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        ... 6 more
    Suppressed: java.lang.RuntimeException: Error scanning entry META-INF/versions/9/jodd/util/UnsafeUtil.class from jar file:///D:/MyProjects/java/demo/jodd41/web/WEB-INF/lib/jodd-all-4.1.1.jar
        at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:906) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationParser.parse(AnnotationParser.java:851) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationConfiguration$ParserTask.call(AnnotationConfiguration.java:163) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationConfiguration$1.run(AnnotationConfiguration.java:546) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
        at java.lang.Thread.run(Thread.java:748) ~[?:1.8.0_152]
    Caused by: java.lang.IllegalArgumentException
        at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
        at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
        at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
        at org.eclipse.jetty.annotations.AnnotationParser.scanClass(AnnotationParser.java:977) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationParser.parseJarEntry(AnnotationParser.java:958) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:902) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
        ... 6 more
Caused by: java.lang.RuntimeException: Error scanning entry META-INF/versions/9/jodd/core/JavaBridge.class from jar file:///D:/MyProjects/java/demo/jodd41/web/WEB-INF/lib/jodd-all-4.1.1.jar
    at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:906) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationParser.parse(AnnotationParser.java:851) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationConfiguration$ParserTask.call(AnnotationConfiguration.java:163) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationConfiguration$1.run(AnnotationConfiguration.java:546) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at java.lang.Thread.run(Thread.java:748) ~[?:1.8.0_152]
Caused by: java.lang.IllegalArgumentException
    at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
    at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
    at org.objectweb.asm.ClassReader.<init>(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
    at org.eclipse.jetty.annotations.AnnotationParser.scanClass(AnnotationParser.java:977) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationParser.parseJarEntry(AnnotationParser.java:958) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:902) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationParser.parse(AnnotationParser.java:851) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationConfiguration$ParserTask.call(AnnotationConfiguration.java:163) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.annotations.AnnotationConfiguration$1.run(AnnotationConfiguration.java:546) ~[jetty-annotations-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) ~[jetty-util-9.3.21.v20170918.jar:9.3.21.v20170918]
    at java.lang.Thread.run(Thread.java:748) ~[?:1.8.0_152]
23:27:10.616 INFO  org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@53416032{HTTP/1.1,[http/1.1]}{0.0.0.0:80}
23:27:10.632 INFO  org.eclipse.jetty.server.Server - Started @3837ms

@moh-sushi After remove the folder of versions from jodd-all-4.1.1.jar. the log world is so beauty!!! thanks very much! @moh-sushi

bentolor commented 6 years ago

Same here – stumbling over this right now on upgrading a one year old Jodd / Madvoc application.

igr commented 6 years ago

Ok, I will try to make a java8-only version of the jar - or maybe the opposite, to have java8 by default and the java9 version as a classifier.

@bentolor if you need any help, please let me know! There are changes in Madvoc, but most are cosmetic, so you should be able to migrate rather easily, although it is not trivial. Anyway, you can also try the Joy, as it makes things even easier. Just ping me with anything you need :)

bentolor commented 6 years ago

@igr Thanks for jumping in so quickly!

"Application" is a little exaggerated: I'm porting my showcase application to the latest version, because I'm going to present a comparison of Java "microframeworks" on the german Javaland conference which tries to "compare" Jodd with a few other candidates (Ratpack, Sparkjava, Ninja, Bootstrap).

I used this as basis for my article on heise developer comparing those framworks (german, sorry)

So far I really liked the changes which overall provide an even more concise legibility. As a all-purpose Microframework Jodd is my favourite. I recommended it it strongly due to it's cleanliness and good documentation.

igr commented 6 years ago

Thank you @bentolor for kind words! Please note that now, in v4, is more clear (or clean:) how to build a REST api (see: https://github.com/oblac/todo-backend-jodd) or common web app (see: https://github.com/oblac/tutorial).

Again, thank you very much!!!

bentolor commented 6 years ago

@igr Great! The todo backend is more or less exactly what I'm replicating for a shopping list. Will take a look to benefit from v4 as much as possible.

moh-sushi commented 6 years ago

my original thoughts for 4.1.2 :

Ok, I will try to make a java8-only version of the jar - or maybe the opposite, to have java8 by default and the java9 version as a classifier.

But i like the approach for making a jodd-core-4.1.2-jre9.jar , too :-)

Let me know if i can help you!

igr commented 6 years ago

You are right @moh-sushi, this is the way to go.

I will check now how Gradle makes artifacts with the classifiers, that is the only place where I can do the change :)

igr commented 6 years ago

@moh-sushi would you be so kind to try if jodd-core-4.1.2-jdk8.jar works for you? Just released on Maven, but didn't want to make it public until we are sure it works. This should be a classifier (jdk8)

Damn, I just realized I used the jdk word, instead of jre :((( I think I saw Guice is using the same name... Damn, I hope this naming does not make a difference, wdyt?

igr commented 6 years ago

This didnt worked. I will try again. Gradle :( will migrate to new publish plugin. Hope I will made it

moh-sushi commented 6 years ago

Good Morning,

This didnt worked

I can confirm ;-) - I have found no jdk8-jar-file -> http://repo1.maven.org/maven2/org/jodd/jodd-core/4.1.2/

Damn, I just realized I used the jdk word, instead of jre :((( I think I saw Guice is using the same name... Damn, I hope this naming does not make a difference, wdyt?

I prefer jre-classifier.

And it looks better for me :-)

igr commented 6 years ago

@moh-sushi There is the following issue now... I have the fix locally, but:

you can specify:

        <dependency>
            <groupId>org.jodd</groupId>
            <artifactId>jodd-core</artifactId>
            <version>4.1.3</version>
            <classifier>jre8</classifier>
        </dependency>

but other Jodd dependencies will still require the default one, w/o a classifier. As a result, both jars will be included in the war, and it will still fail.

igr commented 6 years ago

I am looking for other solutions:

https://stackoverflow.com/questions/48590523/can-mr-jars-overwrite-classes-from-other-jars

But if that does not work, the only solution seems to have two separate releases. Urgh :(

igr commented 6 years ago

Maybe I should remove any Java9 work for good. There is no Jodd user that I am aware of that is using java9. This makes things only complicated.

The key issue is only the few classes in jodd-core-9 package. Maybe if I move those... or something.

moh-sushi commented 6 years ago

but other Jodd dependencies will still require the default one, w/o a classifier. As a result, both jars will be included in the war, and it will still fail.

Ahh, yes - i see. Workaround may be to exclude jodd-core (without classifer). But it is not "sexy" ...

moh-sushi commented 6 years ago

I am looking for other solutions: https://stackoverflow.com/questions/48590523/can-mr-jars-overwrite-classes-from-other-jars

Let us see if an answer will help us...

But if that does not work, the only solution seems to have two separate releases. Urgh :(

urgh...

moh-sushi commented 6 years ago

Maybe I should remove any Java9 work for good. There is no Jodd user that I am aware of that is using java9. This makes things only complicated.

conclusion : jodd will not be compatible with java 9 anymore?

igr commented 6 years ago

well, only few parts: there would be no automagic detection and it would require to enable the unsafe module... i might add jre9 artifact instead (ie to invert this proposal). i simply dont know what else todo. :(

igr commented 6 years ago

The only thing I can think of is cross-compilation... and releasing everything for Java8 and Java9.

I am not sure if i have the bandwidth for that :(

bentolor commented 6 years ago

i might add jre9 artifact instead (ie to invert this proposal).

The current situation is, that we have a full functionality loss for users of Java 8 an below vs. a limited loss of functionality for Java 9+ users. So I think this speaks for a dedicated jre9+ solution.

I think it's key to stick with an as-simple-as-possible solution for users: Similar to rubys principle of least surprise. One should be able to just include the default dependency and it should "just work" as far as possible.

The only thing I can think of is cross-compilation... and releasing everything for Java8 and Java9.

Not sure how that would look : completely separated releases of all jodd-components? Urgh!

moh-sushi commented 6 years ago

Hi,

what about this proposal:

the default jre target will be java 8 that is all jodd modules do not have java 9 class files under META-INF/versions.

the jodd-all-module will be changed a little bit: the default jodd-all artefact will not have any java 9 class files. but there is a jre9-classifier - only this extra artefact will have the java 9 class files included.

If a user runs jodd in jre 9 environment it has to use the jodd-all-jre9.jar if the user has any problems due to classloader. I think the size of jodd-all.jar does not matter.

some changes for the jodd-all.pom are needed, too. the only added dependencies may the provided deps from the jodd modules. the current deps in jodd-all.pom - like

<dependency>
    <groupId>org.jodd</groupId>
    <artifactId>jodd-bean</artifactId>
    <version>4.1.2</version>
    <scope>compile</scope>
</dependency>

should be deleted / not added in generated pom.

These dependencies are not needed anyway, because all class files from all jodd modules are integrated in the jodd-all.jar.

Or do I have a misconception?

WDYT?

igr commented 6 years ago

@moh-sushi @bentolor you are right... thank you!

im publishing now v4.1.3, got it all sorted out; for Java9 there is a solution, but only with Gradle as far as i know; I have to sleep now, but tomorrow will test again everything and explain here

igr commented 6 years ago

@moh-sushi @bentolor

Here it is: v4.1.4 :)

It is like you said: the default is Java8. Everything is set and optimized for it. jodd-core will work now on Java8 and your examples should work out-of box.

For Java9, here is the deal: https://jodd.org/download/#java-9-i-classfa-fa-coffeei

You simply have to exclude the transitive dependency and force usage of one with the classifier jre9. I do not know if this is possible with Maven, but at least it is possible with Gradle.

Regarding the jodd-all - it's really a special case; i would rather have people using the real dependencies then the all. To be honest, it is there only because I need to create a javadoc for the whole jodd ;)

You are right for the jodd-all.pom @moh-sushi, hm. I need to fix that in other commit. Maybe we don't need to publish it at all.

bentolor commented 6 years ago

Thanks, @igr for sorting this out. Works now for me again and looks like an appropriate and documented solution.

moh-sushi commented 6 years ago

Thank you, @igr ! Jodd works as usual with Java 8 out of the box again.