使用外部jar的弹簧启动'不是托管类型'

时间:2016-09-12 16:27:37

标签: java spring maven jar

我有一个弹簧应用程序正在拉入一个公共罐子。这个jar有DTO类和注释。运行mvn clean build命令成功运行并构建jar。一旦我运行java -jar target / MyApp-1.0.0.BUILD-SNAPSHOT.jar,我将得到以下错误。

我已经打开MyApp-1.0.0.BUILD-SNAPSHOT.jar并在该jar中找到了我的所有类。

我在快照中打开了包含MyApplicationJobDTO的jar,并验证了该文件是否存在。

似乎在运行时java无法找到类,即使类在那里。我不相信我应该向java类路径添加任何东西,因为jar位于快照jar内。我陷入困境,不确定为什么我会遇到运行时错误。

Caused by: java.lang.IllegalArgumentException: Not an managed type: class com...MyApplicationJobDTO

带有注释的类

@Component
@Entity
public class MyApplicationJobDTO implements Serializable {

我的命令

mvn clean package && java -jar target/MyApp-1.0.0.BUILD-SNAPSHOT.jar 

我的主要课程

@EnableJpaRepositories
@ComponentScan
@EntityScan
@Configuration
@EnableAutoConfiguration
public class Application {
    public static void main(String[] args) {

        ApplicationContext context = 
                new ClassPathXmlApplicationContext("file:src/main/java/com/myapp/beans.xml");

        SpringApplication.run(Application.class, args);
    }
}

的beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

</beans>

错误

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyApplicationJobController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myapp.xx.yy.models.MyApplicationJobDAO com.myapp.xx.yy.web.MyApplicationJobController.MyApplicationJobDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyApplicationJobDAO': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.myapp.aa.bb.myapptest.commons.dto.MyApplicationJobDTO
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:293)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
    at com.myapp.xx.yy.Application.main(Application.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myapp.xx.yy.models.MyApplicationJobDAO com.myapp.xx.yy.web.MyApplicationJobController.MyApplicationJobDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyApplicationJobDAO': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.myapp.aa.bb.myapptest.commons.dto.MyApplicationJobDTO
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:509)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:290)
    ... 22 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyApplicationJobDAO': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.myapp.aa.bb.myapptest.commons.dto.MyApplicationJobDTO
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1554)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1021)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:964)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:481)
    ... 24 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not an managed type: class com.myapp.aa.bb.myapptest.commons.dto.MyApplicationJobDTO
    at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:219)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68)
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:149)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:88)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:68)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:158)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)

编辑如果我手动添加我的外部jar中需要在我的spring项目中使用的所有类,它就可以工作。我仍然无法从外部jar加载类

6 个答案:

答案 0 :(得分:3)

您的应用程序包可能与您的DTO类不同,因此Spring无法找到它。你可以做到

@ComponentScan("com.myapp.xx.yy.models")

答案 1 :(得分:3)

删除@EntityScan 已弃用。如果您使用@EntityScan,它将覆盖@ComponentScan

您应指定要扫描JPA实体的基础包。 的 @EntityScan(&#34; com.myapp.xx.yy.models&#34)

答案 2 :(得分:0)

我在这里给出了相同的答案:https://stackoverflow.com/a/41145229/372838但是这个问题更清楚地说明了问题只发生在将Spring引导应用程序作为JAR运行时

在我的项目中,我们遇到了类似的问题。使用mvn spring-boot:start运行时,@EntityScan工作正常,可以找到所有实体,包括库中的实体。当我们使用java -jar运行springboot应用程序时,应用程序找不到通过maven依赖项引用的实体。当springboot应用程序作为jar运行时,类加载似乎不同。

你可以指示弹簧靴解包&#39;包含无法找到的实体的JAR依赖项。您可以将以下部分添加到pom.xml

<project>
  ...

  <build>
      <plugins>
          <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
              <configuration>
                  <requiresUnpack>
                      <dependency>
                          <groupId>nl.ocwduo.ces.commons</groupId>
                          <artifactId>domain-jar</artifactId>
                      </dependency>
                  </requiresUnpack>
              </configuration>
          </plugin>
      </plugins>
  </build>

</project>

答案 3 :(得分:0)

与dvtoever类似,我也将我的答案添加到了链接的问题中,但是会在此处添加它,以防将来对某人有帮助。


我的项目在Spring Boot应用程序中也有类似的问题。我在@Entity之类的包中的公共jar中有com.foo.jpa类,然后有一个依赖于公共jar的应用程序jar。应用程序jar在诸如@SpringBootApplication之类的软件包中具有主com.foo.bar.appname类。 @EntityScan@ComponentScan@EnableJpaRepositories均未检测到@Entity类,并且给出了“不是托管类型”错误,无论我为注释提供了什么包名称。 / p>

我终于通过重命名程序包名称来修复它。我将@SpringBootApplicationapplication类放在com.foo.bar处,并将@Entity类放在公共罐中的com.foo.bar.whatever处。只要公共jar中的@Entity类位于@SpringBootApplication类的同一包或子包中,无论它位于哪个jar中,它都将被自动检测到。

答案 4 :(得分:0)

我相信答案来晚了,但是,在相同的情况下,我的实体和存储库都存放在外部jar文件中。经过多次尝试,我找到了解决方案,方法是使用@SpringBootApplication参数声明@ComponentScanbasePackage

@ComponentScan(basePackages = { "com.external.yourExternalPackage.*" })
@EnableJpaRepositories
@EntityScan(basePackages = { "com.external.model.foo.entity" })
@SpringBootApplication
@EnableConfigurationProperties
public class Application {
    public static void main(String[] args) {


    SpringApplication.run(Application.class, args);
  }
}

谢谢。

答案 5 :(得分:0)

我遇到了类似的问题,我通过添加此类来解决了这个问题:

@EntityScan(basePackages = { "com.internal.model", "com.external.model" })
@Configuration
public class ScanJPA {}

确保同时包含内部和在依赖项(外部jar)中定义的JPA实体的根包。