जब मैं स्कैला आरईपीएल में निम्न कोड निष्पादित करता हूं:

javax.persistence.Persistence.createEntityManagerFactory("manager1")

मुझे समझ आ गया

javax.persistence.PersistenceException: No Persistence provider for EntityManager named manager1

जावा चलाने वाले एक ही मेवेन प्रोजेक्ट में कोई समस्या नहीं है (दूसरे शब्दों में, मेरा मानना ​​​​है कि मेरी निर्भरता सही तरीके से स्थापित है)

रिमोट डीबगर का उपयोग करके मैंने पाया कि समस्या PersistenceProviderResolverHolder पर प्रतीत होती है जहां उसने निम्न कोड निष्पादित किया:

Enumeration<URL> resources = cl.getResources( "META-INF/services/" + PersistenceProvider.class.getName() )

लौटाई गई गणना में कोई तत्व नहीं है।

जब मैं उसी आरईपीएल सत्र को निष्पादित करता हूं

val cl = classOf[javax.persistence.spi.PersistenceProviderResolverHolder].getClassLoader()
cl.getResources( "META-INF/services/javax.persistence.spi.PersistenceProvider").hasMoreElements

मुझे "सच" मिलता है

यह एमवीएन का उपयोग करते समय होता है: स्कैला या सीधे स्कैला का उपयोग करते समय:

scala -cp "target/dependency/*":target/classes

मेरी निर्भरताएँ हैं

[INFO] --- maven-dependency-plugin:2.3:tree (default-cli) @ java.jpa.basics ---
[INFO] com.edc4it:java.jpa.basics:jar:1.0
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.6.2:compile
[INFO] |  +- org.slf4j:slf4j-api:jar:1.6.2:compile
[INFO] |  \- log4j:log4j:jar:1.2.16:compile
[INFO] +- mysql:mysql-connector-java:jar:5.1.6:compile
[INFO] +- javassist:javassist:jar:3.9.0.GA:compile
[INFO] +- org.scala-lang:scala-library:jar:2.9.1:compile
[INFO] \- org.hibernate:hibernate-entitymanager:jar:3.6.7.Final:compile
[INFO]    +- org.hibernate:hibernate-core:jar:3.6.7.Final:compile
[INFO]    |  +- antlr:antlr:jar:2.7.6:compile
[INFO]    |  +- commons-collections:commons-collections:jar:3.1:compile
[INFO]    |  +- dom4j:dom4j:jar:1.6.1:compile
[INFO]    |  +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile
[INFO]    |  \- javax.transaction:jta:jar:1.1:compile
[INFO]    +- cglib:cglib:jar:2.2:compile
[INFO]    |  \- asm:asm:jar:3.1:compile
[INFO]    \- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.1.Final:compile

केवल जेपीए से संबंधित निर्भरता "org.hibernate: hibernate-entitymanager: 3.6.7.Final" है

यह एक क्लासलोडिंग समस्या की तरह दिखता है, लेकिन क्या यह कुछ अलग हो सकता है?

2
raphaëλ 1 नवम्बर 2011, 11:26

1 उत्तर

सबसे बढ़िया उत्तर

कुछ और खुदाई और डिबगिंग के बाद, मुझे पता चला कि जेपीए कार्यान्वयन वर्तमान ट्रेड के प्रासंगिक क्लासलोडर का उपयोग करता है (जो मेरे मामले में sun.misc.Launcher$AppClassLoader है)। उस क्लासलोडर में वास्तव में जेपीए और हाइबरनेट जेएआर शामिल नहीं हैं। (देखें javax.persistence.spi.PersistenceProviderResolverHolder.PersistenceProviderResolverPerClassLoader#getContextualClassLoader) EntityManagerFactory प्राप्त करने से पहले प्रासंगिक क्लासलोडर को बदलना इसलिए चाल करता है:

Thread.currentThread().setContextClassLoader(JPAUtil.class.getClassLoader());
emf =  Persistence.createEntityManagerFactory("manager");

आरईपीएल सेटिंग में प्रासंगिक क्लासलोडर काम नहीं करता है, इसे सेट करने के बाद इसे एप्लिकेशन क्लासलोडर पर रीसेट कर दिया जाता है।

मुझे नहीं पता कि परिणाम अभी तक क्या हैं (सुनिश्चित नहीं है कि सभी जेपीए कोड वास्तव में काम करेंगे, बस कुछ परीक्षण किए और अब तक काम करने लगते हैं)। इसके अलावा मुझे समझ में नहीं आता कि हाइबरनेट प्रासंगिक क्लासलोडर का उपयोग क्यों करेगा, न केवल वर्तमान क्लासलोडर।

1
raphaëλ 3 नवम्बर 2011, 13:40