1> सारांश
प्रारंभ में, मैंने जेबॉस 5.1.0.जीए के साथ हाइबरनेट 3.6.4 जार लोड करने के लिए इस क्लास लोडिंग अलगाव की कोशिश की है।
यह निश्चित रूप से संभव नहीं है। हुड के नीचे कुछ जादू है जो आपको जेपीए 2 समर्थन के साथ किसी भी हाइबरनेट संस्करण का उपयोग करने से रोकता है।
मैं वास्तव में को निराश करता हूं कि जेबॉस प्रोजेक्ट ने 5.1.0.जी.ए. पर जेपीए 2 का समर्थन करने के लिए किसी प्रकार का पैच या सर्विस पैक प्रदान नहीं किया था।
2> कारगर युक्तियाँ: "द कर्नेल समाधान"
मैं JBoss 5.1.0.GA साथ JPA2 उपयोग करने के लिए मैं यहां अपने नुस्खा का वर्णन कामयाब रहे। यह अवधारणा का एक सबूत है जिसका उपयोग आप अपना स्वयं का समाधान करने के लिए कर सकते हैं।
सामग्री:
- 1 युद्ध संग्रह
- 1 सर्वलेट
- 1 स्टैंडअलोन जावा आवेदन (J2SE)
पकाने की विधि:
चरण 1: स्टैंडअलोन एप्लिकेशन (एपीपी)
इस एप्लिकेशन को हाइबरनेट का उपयोग करने के लिए सर्वलेट से निर्देश प्राप्त होंगे।
मैं आपको संचार विधि का विकल्प छोड़ देता हूं। जैसा कि एपीपी जेपीए 2 का उपयोग करता है, उसे META-INF
फ़ोल्डर में स्थित persistence.xml
फ़ाइल की आवश्यकता होगी। जेबॉस 5.x के बाद, जब आप एक युद्ध तैनात करते हैं, तो जेबॉस अंधेरे से persistence.xml
फ़ाइलों को ढूंढने और तैनात करने के लिए युद्ध और उसके सभी उप-तैनाती को स्कैन करेगा। उदाहरण के लिए my-persistence.xml
में अपनी persistence.xml
फ़ाइल का नाम बदलें। जब आप अपना EntityManagerFactory
बनाते हैं तो नीचे दिए गए कोड का उपयोग करें (जेबॉस को persistence.xml को तैनात करने से रोकें)।
अद्यतन: यह विधि काम करती है लेकिन कुछ अजीब चेतावनियां हाइबरनेट द्वारा उठाई जाती हैं। उन चेतावनियों को रोकने के लिए, मैंने WAR के बाहर META-INF
फ़ोल्डर और दृढ़ता फ़ाइल (अब वापस persistence.xml
पर नामित) डालने का निर्णय लिया है। मेरे मामले में, मैंने हार्ड ड्राइव पर एक विशेष कॉन्फ़िगरेशन फ़ोल्डर चुना और इसे क्लासपाथ में जोड़ा। दृढ़ता फ़ाइल लोड करने के लिए कोई और अजीब चेतावनी और कोई कस्टम क्लासलोडर आवश्यक नहीं है।
मैं इसे कस्टम क्लास लोडर का उपयोग करने या दृढ़ता फ़ाइल स्थान बदलने के बीच चुनने के लिए छोड़ देता हूं। दोनों मामलों में, जेबॉस को दृढ़ता फ़ाइल नहीं मिलेगी।
चरण 2: सर्वलेट
सर्वलेट डेटाबेस का उपयोग करने की जरूरत है जब निर्माण, यह ऐप्लिकेशन को लॉन्च और यह बताता है कि क्या करना है।
एपीपी को लॉच करने के लिए, सर्वलेट एक नया जेवीएम बनाने और एपीपी के क्लासपाथ का निर्माण करने के लिए ज़िम्मेदार है। नीचे दिए गए कोड को पढ़ें (एक जेवीएम स्पॉइंग)। classpath के बाद से सभी आवश्यक जार युद्ध संग्रह का /lib
निर्देशिका में हो जाएगा आसानी से बनाने योग्य है ...
चरण 3: युद्ध संग्रह
एक युद्ध संग्रह जहां डाल बिल्ड बिल्ड एक जार के रूप में पैक सर्वलेट और स्टैंडअलोन आवेदन। एपीपी युद्ध की निर्भरता होगी।
रोकें JBoss से persistence.xml
// Install a proxy class loader for adding renamed persistence.xml file
Thread t = Thread.currentThread();
ClassLoader clOriginal = t.getContextClassLoader();
t.setContextClassLoader(new SpecialClassLoader(clOriginal, "META-INF/my-persistence.xml"));
// Build EntityManagerFactory
EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName);
// Restore original class loader
t.setContextClassLoader(clOriginal);
//...
private class ProxyClassLoader extends ClassLoader {
private ClassLoader realClassLoader;
private String hiddenFromJBossPersistenceFile;
public ProxyClassLoader(ClassLoader realClassLoader, String hiddenFromJBossPersistenceFile) {
this.realClassLoader = realClassLoader;
this.hiddenFromJBossPersistenceFile = hiddenFromJBossPersistenceFile;
}
public void clearAssertionStatus() {
realClassLoader.clearAssertionStatus();
}
public boolean equals(Object obj) {
return realClassLoader.equals(obj);
}
public URL getResource(String name) {
return realClassLoader.getResource(name);
}
public InputStream getResourceAsStream(String name) {
return realClassLoader.getResourceAsStream(name);
}
public Enumeration<URL> getResources(String name) throws IOException {
ArrayList<URL> resources = new ArrayList<URL>();
if (name.equalsIgnoreCase("META-INF/persistence.xml")) {
resources.add(getResource(this.hiddenFromJBossPersistenceFile));
}
resources.addAll(Collections.list(realClassLoader.getResources(name)));
return Collections.enumeration(resources);
}
public int hashCode() {
return realClassLoader.hashCode();
}
public Class<?> loadClass(String name) throws ClassNotFoundException {
return realClassLoader.loadClass(name);
}
public void setClassAssertionStatus(String className, boolean enabled) {
realClassLoader.setClassAssertionStatus(className, enabled);
}
public void setDefaultAssertionStatus(boolean enabled) {
realClassLoader.setDefaultAssertionStatus(enabled);
}
public void setPackageAssertionStatus(String packageName, boolean enabled) {
realClassLoader.setPackageAssertionStatus(packageName, enabled);
}
public String toString() {
return realClassLoader.toString();
}
}
एक JVM
public static Process createProcess(final String optionsAsString, final String workingDir, final String mainClass, final String[] arguments) throws IOException {
String jvm = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
String[] options = optionsAsString.split(" ");
List<String> command = new ArrayList<String>();
command.add(jvm);
command.addAll(Arrays.asList(options));
command.add(mainClass);
command.addAll(Arrays.asList(arguments));
//System.out.println(command);
ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.directory(new File(workingDir));
return processBuilder.start();
}
public static void makeItRun() {
try {
// Start JVM
String classPath = buildClassPath();
String workingDir = getSuitableWorkingDir();//or just "."
Process java = createProcess("-cp \"" + classPath + "\"", workingDir, my.package.APP.class.getCanonicalName(), "-the -options -of -my -APP");
// Communicate with your APP here ...
// Stop JVM
java.destroy();
} catch(Throwable t) {
t.printStackTrace();
}
}
आप कैसे जानते हैं कि यह अपने स्वयं के जार का उपयोग कर रहा है? – gkamal
@gkamal जब मेरा ऐप चलाया जाता है, तो मुझे 'NoSuchMethod' अपवाद मिला। – Stephan
क्या डब्ल्यूएआर स्वयं पर तैनात है या क्या यह ईएआर का हिस्सा है? – CoolBeans