【问题标题】:How to autowire class in Maven multi module Spring web app?如何在 Maven 多模块 Spring Web 应用程序中自动装配类?
【发布时间】:2015-09-19 03:31:08
【问题描述】:

我正在开发包含 Maven 多模块项目的应用程序。当尝试从另一个模块 @Autowire 服务类时,我得到 java.lang.NoClassDefFoundError: 这个项目的独特之处在于依赖关系在 2 个 Web 模块之间。

父项目


Pom.xml

<project>
    <groupId>com.test.simple-project</groupId>
    <artifactId>simple-parent</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>module-x</module>
        <module>module-y</module>
    </modules>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

模块 X


Pom.xml

<project>
    <artifactId>module-x</artifactId>
    <parent>
        <groupId>${project.groupId}</groupId>
        <artifactId>simple-parent</artifactId>
    </parent>
    <packaging>war</packaging>
     <dependencies>
        ...
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>


package com.test.module-x.service;      
@Service("userService")
   public class UserServiceImpl implements UserService {
}

模块 Y


Pom.xml

<project>
    <artifactId>module-y</artifactId>
    <parent>
        <groupId>${project.groupId}</groupId>
        <artifactId>simple-parent</artifactId>
        <version>${project.version}</version>
    </parent>
    <packaging>war</packaging>
     <dependencies>
        <dependency>
            <groupId>com.test.simpleproject</groupId>
            <artifactId>module-x</artifactId>
        </dependency>
        ...
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>


Y中的组件扫描

<context:component-scan base-package="com.test.module-x.service" />


 @Controller
     public class SimpleController {

        @Autowired
        private UserService userService;
    }

两个模块都是Spring mvc web项目(两个pom.xml打包都是war)

运行应用抛出java.lang.NoClassDefFoundError: com/test/module-x/service/UserService

java.lang.NoClassDefFoundError: Lcom/test/module-x/service/UserService;
    at java.lang.Class.getDeclaredFields0(Native Method)
        at java.lang.Class.privateGetDeclaredFields(Class.java:2570)
        at java.lang.Class.getDeclaredFields(Class.java:1903)
        at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:324)
        at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:285)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:846)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:498)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
        at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
        at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
        at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
        at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
        at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
        at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)

有什么想法吗?

【问题讨论】:

  • 很难说除非你包含更多信息 - 最好是一些 pom.xml - 特别是战争插件
  • 包含更多信息

标签: java spring maven spring-mvc


【解决方案1】:

依赖于另一个 WAR 模块的 WAR 模块无权访问依赖模块生成的类。因此,您必须将module-x 中的课程提供给module-y 中的课程。有两种方法可以做到。

选项 1:更简洁的设计


将公共类抽象到一个单独的 JAR 模块中,并声明从 module-xmodule-y 到此模块的依赖关系。

选项 2:从 module-y 中的类中获取对 module-x 中声明的类的访问权限


首先,配置module-x中的maven-war-plugin,将类打包成单独的JAR文件。

<project>
  <artifactId>module-x</artifactId>
  <packaging>war</packaging>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <attachClasses>true</attachClasses>
          <classesClassifier>classes</classesClassifier>
        </configuration>
      </plugin>
    </plugins>
  </build>

现在,在module-y 中声明对module-x 的依赖:

<project>
  <artifactId>module-y</artifactId>
  <packaging>war</packaging>

  <dependencies>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>module-x</artifactId>
      <version>${project.version}</version>
      <classifier>classes</classifier>
    </dependency>
  </dependencies>
</project>

【讨论】:

  • 尝试了选项 2,但我遇到了同样的错误。你认为它与组件扫描有关吗?
  • 如果是同一个stacktrace,组件扫描与它无关。如果是组件扫描错误,则会出现No matching bean of type ... found 之类的内容。 Here 是一个工作样本。将其与您的代码进行比较,以找出导致错误的差异。如果这不起作用,请发布一个完整的示例项目来演示您的问题。
  • 感谢您花时间创建示例项目。我正在检查它,会告诉你结果。
  • 刚刚开始在这个项目上工作。您提供的示例项目工作正常,但我更改了 pom.xml 以支持在 eclipse 中定义的服务器上运行应用程序,我得到org.springframework.beans.factory.BeanCreationException:creating bean with name 'fooController' defined in file ...\...\FooController.class]: Post-processing failed of bean type [class org.example.web.FooController] failed; nested exception is java.lang.IllegalStateException: Failed to introspect bean class [org.example.web.FooController] for resource metadata: could not find class that it depends on
【解决方案2】:

您必须在与模块 Y 关联的 pom.xml 文件中定义对模块 X 的输出 war 文件的依赖。 然而,有 2 个 war 文件并在它们之间放置依赖关系是很奇怪的。据我了解,您将拥有 2 个 Web 应用程序。如果我猜对了,模块 X 不知何故是整个系统的业务层(包括服务),因此足以从中生成一个 jar 文件,并且仅将模块 Y 定义为 Web 模块。 不过,您需要在模块 Y 的 pom.xml 文件中对模块 X 有明确的 maven 依赖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    • 1970-01-01
    • 2019-08-13
    • 2018-03-25
    • 2019-03-26
    • 2013-02-03
    相关资源
    最近更新 更多