ninjaframework / ninja

Ninja is a full stack web framework for Java. Rock solid, fast and super productive.
http://www.ninjaframework.org
Apache License 2.0
1.91k stars 518 forks source link

Ninja 6.4.1 completely breaks JPA (Hibernate) in the final application JAR #649

Closed jlannoy closed 5 years ago

jlannoy commented 5 years ago

A library update (probably a transitive dependency) is leading to a big problem when upgrading or starting a project with Ninja > 6.4.1. No problem when building it, but once a shaded jar as been packaged, trying to run it fails.

ninja.lifecycle.FailedStartException: javax.persistence.PersistenceException: Unable to build entity manager factory
    at ninja.lifecycle.LifecycleRegister.invokeTarget(LifecycleRegister.java:103)
    ...
Caused by: javax.persistence.PersistenceException: Unable to build entity manager factory
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:83)
    ...
Caused by: org.hibernate.jpa.boot.archive.spi.ArchiveException: Could not build ClassFile
    at org.hibernate.jpa.boot.scan.spi.ClassFileArchiveEntryHandler.toClassFile(ClassFileArchiveEntryHandler.java:88)
    at org.hibernate.jpa.boot.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:65)
    ...

To reproduce it, you can simply create a new project via the JPA archetype, package it, and try to run it via java -jar.

I found on stackoverflow that it comes from a library version missmatch, it could be javaassist or some logging libraries. I'm looking at the exact problem, but i think it will need an urgent release once fixed ;-)

raphaelbauer commented 5 years ago

Thanks for the report! Any fix would be welcome I guess...

There are also plans to move all the db stuff into a separate module. Then the database modules (including JPA) can evolve independently from Ninja itself... => https://github.com/ninjaframework/ninja-db

The JPA support of Ninja is (imho) not good, because guice-persist is de-facto no longer maintained by google... And Ninja is based on guice-persist...

jlannoy commented 5 years ago

Hi @raphaelbauer

I've just isolated the cause right now. Bumping to the last jetty version in ninja 6.4.1, the version of "asm" (org.ow2.asm) which is used for java bytecode manipulation got updated from 5.0.1 to 6.2. Hibernate uses javaassist for the same purpose. It seems to exist a conflict with 6.2 and javassist.

1) It works if we explicitly set up asm to 5.0.1 in place of 6.2... But it go against jetty's requirements and seems me dirty. Especially if Ninja doesn't need ASM.

2) In fact, asm comes (only) for jetty-annotations, which comes as a dependency of websocket-server-impl. I checked a little bit, and it seems we never need (nor encourage) the use of Jetty annotations (which are in fact javax servlet annotations) while using Ninja : https://www.eclipse.org/jetty/documentation/9.4.x/using-annotations.html So wouldn't it be more accurate to exclude Jetty's annotations from ninja-standalone dependencies?

Both fixes are working... What are your thoughts?

raphaelbauer commented 5 years ago

Nice research :) I think "2" makes most sense. With a big fat comment why we exclude "Jetty annotations".

AllExample commented 5 years ago

Use 6.4.2 I can't run it with java -jar after I have made it into a jar package. What should I do? Can I use version 6.4.2 or higher?

AllExample commented 5 years ago

`13:41:28.201 [NinjaJetty] INFO org.hibernate.cfg.Environment - HHH000021: Bytec ode provider name : javassist 13:41:30.887 [NinjaJetty] INFO o.e.jetty.server.AbstractConnector - Started Ser verConnector@35653d6f{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} 13:41:30.890 [NinjaJetty] ERROR ninja.standalone.NinjaJetty - Unable to start Ni njaJetty ninja.lifecycle.FailedStartException: javax.persistence.PersistenceException: Un able to build entity manager factory at ninja.lifecycle.LifecycleRegister.invokeTarget(LifecycleRegister.java :103) at ninja.lifecycle.LifecycleRegister.start(LifecycleRegister.java:55) at ninja.lifecycle.LifecycleServiceImpl.start(LifecycleServiceImpl.java: 84) at ninja.NinjaDefault.onFrameworkStart(NinjaDefault.java:151) at conf.Ninja.onFrameworkStart(Ninja.java:29) at ninja.Bootstrap.boot(Bootstrap.java:119) at ninja.servlet.NinjaServletListener.createNinjaBootstrap(NinjaServletL istener.java:152) at ninja.servlet.NinjaServletListener.getInjector(NinjaServletListener.j ava:123) at com.google.inject.servlet.GuiceServletContextListener.contextInitiali zed(GuiceServletContextListener.java:45) at ninja.servlet.NinjaServletListener.contextInitialized(NinjaServletLis tener.java:75) at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialize d(ContextHandler.java:952) at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialize d(ServletContextHandler.java:558) at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextH andler.java:917) at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletC ontextHandler.java:370) at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandle r.java:847) at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContex tHandler.java:287) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLife Cycle.java:68) at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLi feCycle.java:138) at org.eclipse.jetty.server.Server.start(Server.java:416) at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(Container LifeCycle.java:108) at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHand ler.java:113) at org.eclipse.jetty.server.Server.doStart(Server.java:383) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLife Cycle.java:68) at ninja.standalone.NinjaJetty.doStart(NinjaJetty.java:167) at ninja.standalone.AbstractConsole.start(AbstractConsole.java:77) at ninja.standalone.AbstractStandalone.run(AbstractStandalone.java:113) at ninja.standalone.NinjaJetty.main(NinjaJetty.java:70) Caused by: javax.persistence.PersistenceException: Unable to build entity manage r factory at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFac tory(HibernatePersistenceProvider.java:83) at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(Hib ernatePersistence.java:54) at javax.persistence.Persistence.createEntityManagerFactory(Persistence. java:55) at com.google.inject.persist.jpa.JpaPersistService.start(JpaPersistServi ce.java:109) at ninja.jpa.JpaInitializer.start(JpaInitializer.java:52) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at ninja.lifecycle.LifecycleRegister.invokeTarget(LifecycleRegister.java :96) ... 26 common frames omitted Caused by: org.hibernate.jpa.boot.archive.spi.ArchiveException: Could not build ClassFile at org.hibernate.jpa.boot.scan.spi.ClassFileArchiveEntryHandler.toClassF ile(ClassFileArchiveEntryHandler.java:88) at org.hibernate.jpa.boot.scan.spi.ClassFileArchiveEntryHandler.handleEn try(ClassFileArchiveEntryHandler.java:65) at org.hibernate.jpa.boot.archive.internal.JarFileBasedArchiveDescriptor .visitArchive(JarFileBasedArchiveDescriptor.java:176) at org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl.scan(AbstractScan nerImpl.java:72) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.scan( EntityManagerFactoryBuilderImpl.java:725) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init

(EntityManagerFactoryBuilderImpl.java:221) at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(B ootstrap.java:51) at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactor yBuilder(HibernatePersistenceProvider.java:182) at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactor yBuilderOrNull(HibernatePersistenceProvider.java:131) at org.hibernate.ejb.HibernatePersistence.getEntityManagerFactoryBuilder OrNull(HibernatePersistence.java:93) at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactor yBuilderOrNull(HibernatePersistenceProvider.java:88) at org.hibernate.ejb.HibernatePersistence.getEntityManagerFactoryBuilder OrNull(HibernatePersistence.java:101) at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFac tory(HibernatePersistenceProvider.java:69) ... 35 common frames omitted`

AllExample commented 5 years ago

@jlannoy Hello, my project has been developed using this version of 6.4.2, can not run after being labeled as a jar, may I ask how I should deal with the problems I have encountered now? Very anxious, thank you!

jlannoy commented 5 years ago

Hello.

To deal with this bug, you can exclude yourself the jetty-annotations from your projet, from the ninja-standalone dependency. Like this :

        <dependency>
            <groupId>org.ninjaframework</groupId>
            <artifactId>ninja-standalone</artifactId>
            <version>${ninja.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-annotations</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
jlannoy commented 5 years ago

Resolved with v6.5.0

sroctadian commented 3 years ago

Hi, Currently i'm using ninjaframework

6.8.1 9.4.35.v20201120 it work fine until i add okhttp3 and now i'm facing the same issue. com.squareup.okhttp3 okhttp 4.9.0 i've tried to add exclusions but still not working. javassist org.javassist org.eclipse.jetty jetty-annotations may i ask for your guidance to solve this problem. thank u