ढूँढेंResource("") जब मॉड्यूल-info.java मौजूद है, तो अशक्त क्यों लौट रहा है?




spring-boot java-10 (4)

आप पर निर्भरता की घोषणा की है:

<dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>javax.transaction-api</artifactId>
    <version>1.3</version>
</dependency>

module-info.java में निम्नलिखित शामिल करें:

requires java.transaction;

संस्करण 1.3 स्वचालित मॉड्यूल नाम घोषित करता है, जबकि संस्करण 1.2 नहीं है।
बाद में requires javax.transaction.api;Source

मैं डिबग कर रहा हूं कि मेरे स्प्रिंग बूट एप्लिकेशन में module-info.java की उपस्थिति में, spring-orm module-info.java प्रारंभ समय के दौरान एक अपवाद क्यों फेंकता है। यह अपवाद है:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/transaction/UserTransaction
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1699) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089) ~[spring-context-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859) ~[spring-context-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.4.RELEASE/org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.4.RELEASE.jar:na]
    at spring.[email protected].0.4.RELEASE/org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) [spring-boot-2.0.4.RELEASE.jar:na]
    at spring.[email protected].0.4.RELEASE/org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:398) [spring-boot-2.0.4.RELEASE.jar:na]
    at spring.[email protected].0.4.RELEASE/org.springframework.boot.SpringApplication.run(SpringApplication.java:330) [spring-boot-2.0.4.RELEASE.jar:na]
    at spring.[email protected].0.4.RELEASE/org.springframework.boot.SpringApplication.run(SpringApplication.java:1258) [spring-boot-2.0.4.RELEASE.jar:na]
    at spring.[email protected].0.4.RELEASE/org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.4.RELEASE.jar:na]
    at tech.flexpoint.dashmanserver/tech.flexpoint.dashmanserver.DashmanServerApplication.main(DashmanServerApplication.java:13) [classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at spring.boot.[email protected].0.4.RELEASE/org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.0.4.RELEASE.jar:na]
Caused by: java.lang.NoClassDefFoundError: javax/transaction/UserTransaction
    at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
    at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3119) ~[na:na]
    at java.base/java.lang.Class.privateGetPublicMethods(Class.java:3144) ~[na:na]
    at java.base/java.lang.Class.getMethods(Class.java:1863) ~[na:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.service.internal.AbstractServiceRegistryImpl.applyInjections(AbstractServiceRegistryImpl.java:288) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:279) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:239) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.getService(SessionFactoryServiceRegistryImpl.java:80) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.internal.SessionFactoryImpl.canAccessTransactionManager(SessionFactoryImpl.java:942) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.internal.SessionFactoryImpl.buildCurrentSessionContext(SessionFactoryImpl.java:953) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:319) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.[email protected].2.17.Final/org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892) ~[hibernate-core-5.2.17.Final.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.[email protected].0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695) ~[spring-beans-5.0.8.RELEASE.jar:na]
    ... 21 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.transaction.UserTransaction
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499) ~[na:na]
    ... 42 common frames omitted

मैंने समस्या को URLClassLoader.findResource("") लौटाया है यदि module-info.java वापस आ रहा है, लेकिन "file:/C:/Users/pupeno/Documents/Dashman/code/dashmanserver/target/classes/" यह।

मैंने न्यूनतम संभव उदाहरण बनाया जो समान अपवाद को फेंकता है। इसे चलाने के लिए, आपको निम्न करने की आवश्यकता है:

  1. यहां से मोडिटेक की हाल की प्रति को क्लोन और स्थापित करें: https://github.com/moditect/moditect इस बग फिक्स के कारण अभी तक बाहर नहीं होने के कारण: https://github.com/moditect/moditect/issues/51
  2. डेमो रेपो से क्लोन करें: https://github.com/dashmantech/demo
  3. एक स्थानीय PostgreSQL डेटाबेस को क्रेडेंशियल डेमो / confi / application.properties के साथ सेट करें
  4. पहले mvan mvn clean package चलाएं, ताकि मोदीटेक सभी मॉड्यूल तैयार करे
  5. IntelliJ की हालिया कॉपी में प्रोजेक्ट खोलें
  6. "रन डेमो" प्रोफ़ाइल के लिए प्ले पर क्लिक करें ( .idea डायरेक्टरी उपयुक्त रन प्रोफ़ाइल के साथ, तर्कों आदि के साथ शामिल है)।

मुझे findResource("") की आवश्यकता है "file:/C:/Users/pupeno/Documents/Dashman/code/dashmanserver/target/classes/" ताकि spring-orm "file:/C:/Users/pupeno/Documents/Dashman/code/dashmanserver/target/classes/" काम कर सके।

findResource("") इस तरह दिखता है:

public URL findResource(final String name) {
    /*
     * The same restriction to finding classes applies to resources
     */
    URL url = AccessController.doPrivileged(
        new PrivilegedAction<>() {
            public URL run() {
                return ucp.findResource(name, true);
            }
        }, acc);

    return url != null ? URLClassPath.checkURL(url) : null;
}

इसलिए मैं देख सकता हूं कि मॉड्यूल सिस्टम का उपयोग किए बिना कुछ ठीक चल रहा है, लेकिन यह जावा के मॉड्यूल सिस्टम द्वारा रोका जाता है जब एक module-infe.java मौजूद होता है। मेरी समस्या यह है कि मैं यह नहीं देखता कि इसे कैसे काम किया जाए, इसे काम करने के लिए क्या निर्यात या खोलना चाहिए?

जिस तरह से स्प्रिंग बूट उस पद्धति की कॉल का कारण बन रहा है वह है, RestartClassLoader , RestartClassLoader उपवर्ग के URLClassLoader , विशेष रूप से, लाइन 124 जो super.findResource(name) को कॉल करता है:

@Override
public URL findResource(String name) {
    final ClassLoaderFile file = this.updatedFiles.getFile(name);
    if (file == null) {
        return super.findResource(name);
    }
    if (file.getKind() == Kind.DELETED) {
        return null;
    }
    return AccessController
            .doPrivileged((PrivilegedAction<URL>) () -> createFileUrl(name, file));
}

विशिष्ट RestartClassLoader उदाहरण का उपयोग किया जा रहा है, ClassPathResource सदस्य है और इसे इस तरह परिभाषित किया गया है:

this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());

कंस्ट्रक्टर में, पंक्ति 85

अंत में, getDefaultClassLoader() इस तरह दिखता है:

/**
 * Return the default ClassLoader to use: typically the thread context
 * ClassLoader, if available; the ClassLoader that loaded the ClassUtils
 * class will be used as fallback.
 * <p>Call this method if you intend to use the thread context ClassLoader
 * in a scenario where you clearly prefer a non-null ClassLoader reference:
 * for example, for class path resource loading (but not necessarily for
 * {@code Class.forName}, which accepts a {@code null} ClassLoader
 * reference as well).
 * @return the default ClassLoader (only {@code null} if even the system
 * ClassLoader isn't accessible)
 * @see Thread#getContextClassLoader()
 * @see ClassLoader#getSystemClassLoader()
 */
@Nullable
public static ClassLoader getDefaultClassLoader() {
    ClassLoader cl = null;
    try {
        cl = Thread.currentThread().getContextClassLoader();
    }
    catch (Throwable ex) {
        // Cannot access thread context ClassLoader - falling back...
    }
    if (cl == null) {
        // No thread context class loader -> use class loader of this class.
        cl = ClassUtils.class.getClassLoader();
        if (cl == null) {
            // getClassLoader() returning null indicates the bootstrap ClassLoader
            try {
                cl = ClassLoader.getSystemClassLoader();
            }
            catch (Throwable ex) {
                // Cannot access system ClassLoader - oh well, maybe the caller can live with null...
            }
        }
    }
    return cl;
}

मेरे module-info.java में शामिल हैं:

module tech.flexpoint.dashman {
    exports tech.flexpoint.dashman to com.fasterxml.jackson.databind;
    exports tech.flexpoint.dashman.controllers.configurator to javafx.fxml;

    opens tech.flexpoint.dashman to javafx.graphics, jna;
    opens tech.flexpoint.dashman.controllers.common to javafx.fxml;
    opens tech.flexpoint.dashman.controllers.configurator to javafx.fxml;
    opens tech.flexpoint.dashman.models to org.hibernate.validator, tech.flexpoint.dashmancommon, javafx.base;

    opens common;
    opens configurator;
    opens displayer;
    opens winscreensaver;

    requires appdirs;
    requires org.bouncycastle.provider;
    requires com.fasterxml.jackson.core;
    requires com.fasterxml.jackson.databind;
    requires com.fasterxml.jackson.datatype.jdk8;
    requires io.sentry;
    requires jackson.annotations;
    requires java.desktop;
    requires java.sql;
    requires java.validation;
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.graphics;
    requires javafx.media;
    requires javafx.web;
    requires jna;
    requires jna.platform;
    requires org.apache.commons.lang3;
    requires org.kordamp.ikonli.javafx;
    requires org.kordamp.ikonli.fontawesome5;
    requires spring.core;
    requires spring.retry;
    requires spring.web;
    requires tech.flexpoint.dashmancommon;
}

IntelliJ में मेरे पास ये प्लगइन्स सक्षम हैं:

  • लोम्बोक प्लगिन
  • .ginore
  • शक्ति कोशिका
  • VisualVM लॉन्चर
  • ANSI हाइलाइटर
  • बैच लिपियों का समर्थन
  • बायोटेक दर्शक
  • CMD का समर्थन
  • कॉपीराइट
  • कवरेज
  • सीएसएस समर्थन
  • डेटाबेस उपकरण और एसक्यूएल
  • Git एकीकरण
  • GitHub
  • Gradle
  • ग्रूवी
  • हरोकू एकीकरण
  • HTML उपकरण
  • HTTP क्लाइंट
  • l18n जावा के लिए
  • आईडीई सेटिंग्स सिंक
  • जावा बाइटकोड डिकम्पॉइलर
  • जावा ईई: ईजेबी, जेपीए, सर्वलेट्स
  • जावा स्ट्रीम डीबगर
  • JavaFX
  • JUnit
  • लाइन्स सॉर्टर
  • मार्कडाउन समर्थन
  • मवन एकता
  • मावेन एकीकरण विस्तार
  • दृढ़ता चौखटे समर्थन करते हैं
  • गुण समर्थन
  • स्माईली सपोर्ट
  • स्प्रिंग AOP / @ AspectJ
  • स्प्रिंग बैच
  • स्प्रिंग बूट
  • स्प्रिंग डेटा
  • स्प्रिंग इंटीग्रेशन पैटर्न
  • वसंत OSGi
  • वसंत सुरक्षा
  • स्प्रिंग सपोर्ट
  • स्प्रिंग वेब सेवाएँ
  • स्प्रिंग वेब सॉकेट
  • टर्मिनल
  • YAML

यह (या समान) मुद्दा पहले से ही GitHub (लेकिन जावा 9 के साथ) पर वसंत-बूट के लिए दायर किया गया था।

मुझे संदेह के तहत https://github.com/moditect/moditect करना होगा, जबकि moditect पर moditect लिए दायर किए गए मुद्दे भी हैं और मुझे आपका issue भी मिल गया है; ASM को 6.2.1 अपडेट करने से कम से कम एक अन्य ब्रेकिंग परिवर्तन को ठीक करता है:

<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm</artifactId>
    <version>6.2.1</version>
</dependency>

जैसा कि आपने अपनी मूल समस्या में उल्लेख किया है, कोड मॉड्यूल-info.java के बिना काम करता है, लेकिन मॉड्यूल-info.java के साथ नहीं। मैं देख सकता हूं कि आपने इस समस्या को समझाने के लिए, एक न्यूनतम परियोजना का निर्माण करने और इस समस्या को हल करने के लिए इतनी मेहनत की है।

आपकी समस्या को देखते हुए यह स्पष्ट है कि मॉड्यूल में से एक URLClassLoader.findResource("") कारण null । हो सकता है कि सूची में से एक मॉड्यूल इस श्रेणी की विधि से आगे निकल रहा हो या अस्पष्ट कार्यान्वयन हो।

आप कम से कम उदाहरण के लिए एक खाली मॉड्यूल-info.java से क्यों नहीं शुरू करते हैं और जब तक हम त्रुटि नहीं देखते हैं, तब तक 1 मॉड्यूल जोड़ते रहें? मेरा मानना ​​है कि इससे हमें अपराधी को खोजने में मदद मिलेगी।


एक बात जो मैंने नोटिस की है, वह यह है कि आपका एप्लिकेशन (यह मानते हुए कि यह tech.flexpoint.dashman में पैक किया tech.flexpoint.dashman ) किसी भी तरह से स्प्रिंग तक नहीं खोला जा सकता है, जिसके परिणामस्वरूप निश्चित रूप से असफल क्लास लोडिंग / अवैध पहुंच हो जाएगी।

मैं module-info.java (आपके स्प्रिंग निर्भरता के आधार पर) में ऐसा कुछ देखने की उम्मीद module-info.java :

opens tech.flexpoint.dashman to spring.core, spring.beans, spring.context;

अपवाद एक NoClassDefFoundError , जो रनटाइम पर फेंका जाता है जब एक वर्ग की वर्ग परिभाषा जिसे संकलित समय पर जाना जाता था , उसे हल नहीं किया जा सकता है, इस मामले में इंटरफ़ेस javax.transaction.UserTransaction , जो Java Transaction API (JTA) का एक हिस्सा है। ।

जैसा कि अन्य ने बताया है, JTA को JDK के साथ नहीं जोड़ा गया है, और एक संकलन निर्भरता के रूप में जोड़ा जाना चाहिए। हालाँकि, जिस वर्ग को UserTransaction वर्ग परिभाषा को लोड करने की आवश्यकता है, वह spring-boot-autoconfigure कलाकृतियों से आता है, जो अपनी स्वयं की निर्भरता के लिए ज़िम्मेदार है ( [email protected] needs [email protected] F [email protected] ), इसलिए आपको निर्भरता के रूप में JTA को जोड़ने की आवश्यकता नहीं होनी चाहिए।

हालाँकि, चूंकि आप अपने स्वयं के ऐप को जावा 9 मॉड्यूल के रूप में पैकेज करना चाहते हैं, इसलिए इसे स्पष्ट रूप से इसकी निर्भरता बताने की आवश्यकता है। spring-boot-autoconfigure अभी तक एक जावा 9 लाइब्रेरी नहीं है, और यह आपके लिए नहीं करता है (यानी सकर्मक रूप से)। JTA के लिए स्वचालित मॉड्यूल का नाम java.transaction , इसलिए आपको java.transaction आवश्यकता को जोड़ना होगा:

requires java.transaction;

मुझे आपका उदाहरण चल रहा है और वास्तव में IntelliJ IDEA से चलने पर NoClassDefFoundError प्राप्त हुआ। स्टैकट्रेस ने एक ClassNotFoundException को वापस इंगित किया, जो ClassNotFoundException समस्याओं को इंगित करता है। चूंकि IDEA वहां से एप्लिकेशन लॉन्च करते समय क्लासपैथ की गणना करता है, मैं यह देखना चाहता था कि क्या मैं एप्लिकेशन को चलाने के लिए spring-boot-maven-plugin का उपयोग करते समय त्रुटि को पुन: उत्पन्न कर सकता हूं।

मैंने IDEA रन कॉन्फ़िगरेशन को spring-boot-maven-plugin कॉन्फ़िगरेशन में कॉपी किया, जैसा कि नीचे दिखाया गया है:

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
      <mainClass>tech.flexpoint.demo.DemoApplication</mainClass>
      <jvmArguments>--show-module-resolution --add-opens=java.base/java.lang=spring.core --add-opens=java.base/java.io=tomcat.embed.core --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED</jvmArguments>
      <workingDirectory>${project.basedir}</workingDirectory>
  </configuration>
</plugin>

तब मैंने mvn spring-boot:run आह्वान किया mvn spring-boot:run और वॉयला, एप्लिकेशन बिना त्रुटियों के सफलतापूर्वक बूट हो गया। मैं केवल यह निष्कर्ष निकाल सकता हूं कि यह इंटेलीजे द्वारा गणना किए गए क्लासपाथ के साथ एक मुद्दा है।