Spring boot with external jar 'Not a Managed Type'

时光毁灭记忆、已成空白 提交于 2020-06-27 11:19:07

问题


I have a spring application that is pulling in a commons jar. This jar has DTO classes with annotations. Running the mvn clean build command runs successfully and builds the jar. Once i run java -jar target/MyApp-1.0.0.BUILD-SNAPSHOT.jar i will get the below error.

I have opend the MyApp-1.0.0.BUILD-SNAPSHOT.jar and found all my classes inside that jar.

I have opened the jar that contains MyApplicationJobDTO inside my snapshot and verified the file is there.

It seems that at runtime java cannot find the class even though the class is there. I dont believe i should have to add anything to java class path since the jar is located inside of the snapshot jar. I am stuck and unsure of why i am getting runtime errors.

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

Class with its annotations

@Component
@Entity
public class MyApplicationJobDTO implements Serializable {

My command to run

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

My Main class

@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>

Error

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)

edit If i manually add all the classes in my external jar that need to be used in my spring project it works. I still cannot get the classes to load from an external jar


回答1:


Remove @EntityScan it is Deprecated. If you use the @EntityScan it will override @ComponentScan

or

you should specify the base package to scan for the JPA entities. @EntityScan("com.myapp.xx.yy.models")




回答2:


Your application package is probably different from that of your DTO class so Spring can't find it. You could do

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



回答3:


I gave the same answer here: https://stackoverflow.com/a/41145229/372838 but this question states more clearly the problem only occurs when running the spring boot application as a JAR


In my project we experienced a similar problem. When running with mvn spring-boot:start the @EntityScan works fine and can find all entities including those in libraries. When we run the springboot application using java -jar the application cannot find entities that are referenced via a maven dependency. It seems the classloading is different when the springboot application is run as a jar.

You can instruct spring-boot to 'unpack' the JAR dependency that contains the entities that can not be found. You can add the following section to your 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>



回答4:


Similar to dvtoever, I also added my answer to the linked question but will add it here in case it helps someone who comes across this in the future.


My project had a similar problem with a Spring Boot application. I had the @Entity class in the common jar at a package such as com.foo.jpa, then an application jar that depended on the common jar. The application jar had the main @SpringBootApplication class at a package such as com.foo.bar.appname. @EntityScan, @ComponentScan, and @EnableJpaRepositories did not detect the @Entity class and gave the "Not a managed type" error regardless of what package names I provided to the annotations.

I finally fixed it by renaming the package names. I put the @SpringBootApplicationapplication class at com.foo.bar and the @Entity class in the common jar at com.foo.bar.whatever. As long as the @Entity class in the common jar was at the same package or a subpackage of the @SpringBootApplication class, it was autodetected, regardless of which jar it was in.




回答5:


I believe the answer is late, however, I had the same situation where my entities and repository are parked in the external jar file. After many tries, I found the solution by declaring @SpringBootApplication and @ComponentScan with the basePackage parameter.

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

Thanks.




回答6:


I had a similar issue, I sorted it out by adding this class:

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

Make sure to include both the root packages of your JPA entities, that internal and that defined in the dependency, external jar.



来源:https://stackoverflow.com/questions/39454806/spring-boot-with-external-jar-not-a-managed-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!