当前位置: 首页 > 知识库问答 >
问题:

当模块信息.java存在时,查找资源(“”) 返回空值,这是为什么?

江飞白
2023-03-14

在<code>模块信息的情况下,我正在调试为什么。java在我的Spring启动应用程序中,Spring orm在启动时抛出异常。这是例外:

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.beans@5.0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1699) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.beans@5.0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.beans@5.0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.beans@5.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.beans@5.0.8.RELEASE/org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.beans@5.0.8.RELEASE/org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.beans@5.0.8.RELEASE/org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.context@5.0.8.RELEASE/org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089) ~[spring-context-5.0.8.RELEASE.jar:na]
    at spring.context@5.0.8.RELEASE/org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859) ~[spring-context-5.0.8.RELEASE.jar:na]
    at spring.context@5.0.8.RELEASE/org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.8.RELEASE.jar:na]
    at spring.boot@2.0.4.RELEASE/org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.4.RELEASE.jar:na]
    at spring.boot@2.0.4.RELEASE/org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) [spring-boot-2.0.4.RELEASE.jar:na]
    at spring.boot@2.0.4.RELEASE/org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:398) [spring-boot-2.0.4.RELEASE.jar:na]
    at spring.boot@2.0.4.RELEASE/org.springframework.boot.SpringApplication.run(SpringApplication.java:330) [spring-boot-2.0.4.RELEASE.jar:na]
    at spring.boot@2.0.4.RELEASE/org.springframework.boot.SpringApplication.run(SpringApplication.java:1258) [spring-boot-2.0.4.RELEASE.jar:na]
    at spring.boot@2.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.devtools@2.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.core@5.2.17.Final/org.hibernate.service.internal.AbstractServiceRegistryImpl.applyInjections(AbstractServiceRegistryImpl.java:288) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:279) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:239) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.getService(SessionFactoryServiceRegistryImpl.java:80) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.internal.SessionFactoryImpl.canAccessTransactionManager(SessionFactoryImpl.java:942) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.internal.SessionFactoryImpl.buildCurrentSessionContext(SessionFactoryImpl.java:953) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:319) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462) ~[hibernate-core-5.2.17.Final.jar:na]
    at hibernate.core@5.2.17.Final/org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892) ~[hibernate-core-5.2.17.Final.jar:na]
    at spring.orm@5.0.8.RELEASE/org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.orm@5.0.8.RELEASE/org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.orm@5.0.8.RELEASE/org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.orm@5.0.8.RELEASE/org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.orm@5.0.8.RELEASE/org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.8.RELEASE.jar:na]
    at spring.beans@5.0.8.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758) ~[spring-beans-5.0.8.RELEASE.jar:na]
    at spring.beans@5.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(“)返回,如果模块信息.java存在,”文件:/C:/用户/pupeno/文档/达什曼/代码/达什曼服务器/目标/类/“,如果不是。

我创建了抛出相同异常的最小可能的例子。要运行它,您需要:

  1. 从此处克隆并安装Moditect的最新副本:由于此错误修复尚未发布,https://github.com/moditect/moditect:https://github.com/moditect/moditect/issues/51
  2. 从克隆演示存储库:https://github.com/dashmantech/demo
  3. 使用凭据设置本地 PostgreSQL 数据库演示/配置/应用程序属性
  4. 首先运行 mvn 清理包,以便 ModiTec 创建所有模块
  5. 在最近的智能J副本中打开项目
  6. 单击“运行演示”配置文件的“播放”(.idea 目录包含在相应的运行配置文件中,带有参数等)。

我需要<code>findResource(“”,这样<code>spring orm就可以工作了。

< code > find resource(" " 如下所示:

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;
}

所以我可以看到,在不使用模块系统的情况下,有一些访问是可以的,但是当<code>模块输入时,Java的模块系统阻止了这种访问。存在java。我的问题是,我不知道如何让它工作,应该导出或打开什么才能让它工作?

Spring Boot导致调用该方法的方式是通过RestartClassLoaderURLClassLoader的子类,具体来说,第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));
}

正在使用的特定< code>RestartClassLoader实例是< code>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中,我启用了这些插件:

  • 龙目岛插件
  • .吉诺尔
  • 强力外壳
  • 可视化VM启动器
  • 安思荧光笔
  • 批处理脚本支持
  • 字节码查看器
  • 厘米图像处理器支持
  • 版权
  • 覆盖
  • 支持
  • 数据库工具和 SQL
  • 吉特集成
  • 吉特哈布
  • 格拉德尔
  • 槽的
  • 赫鲁库集成
  • 工具
  • 以太网客户端
  • l18n for Java
  • IDE 设置同步
  • Java 字节码反编译器
  • Java EE: EJB, 日本特许厅, 服务项目
  • Java 流调试器
  • 爪哇
  • 日本
  • 线分拣机
  • 降价支持
  • 专家集成
  • 专家集成扩展
  • 持久性框架支持
  • 属性支持
  • 斯玛利支持
  • Spring AOP/@AspectJ
  • Spring批次
  • Spring靴
  • Spring数据
  • Spring集成模式
  • Spring操作系统
  • Spring安全
  • Spring支撑
  • Spring网络服务
  • Spring网页套筒
  • 终端
  • 亚姆尔

共有3个答案

方建明
2023-03-14

正如您在原始问题中提到的,代码在没有模块信息的情况下工作.java但不适用于模块信息.java。我可以看到你已经做了所有这些艰苦的工作来解释问题,创建一个最小的项目等等,以深入研究问题。

查看您的问题,很明显其中一个模块导致< code > URL class loader . find resource(" " 返回< code>null。它可能是列表中的一个模块覆盖了这个类方法或者有一个不明确的实现。

为什么不从空模块信息开始。java作为最小的示例,并保持一次添加一个模块,直到我们看到错误?我相信这将有助于我们找到罪犯。

尹赞
2023-03-14

假设您已声明依赖项:

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

模块信息.java中包括以下内容:

requires java.transaction;

版本 1.3 声明自动模块名称,而版本 1.2 则不声明。
后者需要

陆伟
2023-03-14

我注意到的一件事是,您的应用程序(假设它被打包在tech.flexpoint.dashman中)似乎没有以任何方式向Spring开放,这肯定会导致类加载失败/非法访问。

我希望在module-info.java中看到这样的内容(取决于您的Spring依赖项):

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

异常是<code>NoClassDefFoundError</code>,当编译时已知的类的类定义无法解析时,在运行时抛出,在这种情况下是接口<code>javax.transaction。UserTransaction,它是Java事务API(JTA)的一部分。

正如其他人所指出的,JTA没有与JDK捆绑在一起,需要作为编译依赖项添加。但是,需要加载UserTransaction类定义的类来自sping-boot-autoconfiure工件,它负责自己的依赖项(spring-boot-autoconfigure@2.4.0.RELEASEjboss-transaction-spi@7.6.0.Finaljboss-transaction-api_1.2_spec@1.1.1.Final),因此您不需要将JTA作为依赖项添加。

然而,由于您希望将自己的应用程序打包为Java9模块,因此需要显式地声明其依赖关系spring-boot-autoconfigure还不是模块化的Java 9库,并且不为您这样做(即传递)。JTA的自动模块名为<code>java。事务,因此需要在模块info.java中添加需求:

requires java.transaction;

我运行了您的示例,并且在从IntelliJ IDEA运行时确实得到了NoClassDefFoundEror。堆栈跟踪指向类不发现异常,这表示类路径问题。由于IDEA在从那里启动应用程序时会计算类路径,因此我想看看在使用Spring启动maven插件运行应用程序时是否可以重现错误。

我将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>

然后我调用了mvnSpring启动:运行,瞧,应用程序成功启动而没有错误。我只能得出结论,这是 IntelliJ 计算的类路径的问题。

 类似资料:
  • 问题内容: 据我所知,使用或实例化对象分别返回或的新实例。具有 新标识 的新实例对象。 在我实际测试它之前,这对我来说是很清楚的,我注意到它实际上返回了而不是预期的: 如预期的那样,分别使用和创建对象时,也会表现出这种行为: 我可以在状态文档中找到唯一相关的信息: […]例如,return和return 。 如果未提供任何参数,则构造函数将创建一个新的空元组。 可以说,这不足以回答我的问题。 那么

  • 问题内容: 我有这个代码: 由于该应用程序支持其他类型的身份验证,因此我有一个用户模型,该模型具有嵌套的名为local的对象,看起来像 因此,在登录期间,我想检查用户是否提供了密码,但是遇到了这个有趣的问题。我的测试对象如下所示: 但是打印 我哪里做错了? 问题答案: 这是因为您从猫鼬回来的文档对象不会直接访问属性。它使用原型链,因此返回false(我在简化这一点)。 您可以执行以下两项操作之一:

  • 我试图通过使用基于索引的行位置简单地获得df的子集。但是,出于某些原因,以下代码有时返回空数据帧: dist数据帧(帧是索引): 输出: 我一辈子都不明白为什么会发生这种事。

  • 问题内容: 我有2张桌子- : 第二张桌子- : 我只需要选择未取消的预订(在此示例中仅为ID 3)。我可以轻松地选择带有简单条件的已取消,但由于未在此处取消工作,因此我在努力避免未取消。 问题答案: 要么: 第一个版本更直观,但是我认为第二个版本通常可以获得更好的性能(假设您在联接中使用的列上有索引)。 第二个版本有效,因为返回第一个表中所有行的一行。当条件成功,这些行会包括从第二表中的列,就像