1

I am getting the following error on entityManager bean creation, only when I am running a shadowJar.

bootJar or bootRun doesn't give any exception; it works fine. I need to create a shadow jar.

Exception

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elabsEntityManager' defined in class path resource [com/sample/orchestrator/config/ElabsDataSourceConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a parameterized type!
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:609)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1159)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:326)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300)
        at com.sample.orchestrator.OrchestratorApplication.main(OrchestratorApplication.java:27)
Caused by: java.lang.IllegalArgumentException: Not a parameterized type!
        at org.jboss.jandex.Type.asParameterizedType(Type.java:228)
        at org.jboss.jandex.Indexer.resolveTypePath(Indexer.java:768)
        at org.jboss.jandex.Indexer.resolveTypePath(Indexer.java:780)
        at org.jboss.jandex.Indexer.resolveTypePath(Indexer.java:775)
        at org.jboss.jandex.Indexer.resolveTypeAnnotation(Indexer.java:718)
        at org.jboss.jandex.Indexer.resolveTypeAnnotations(Indexer.java:613)
        at org.jboss.jandex.Indexer.index(Indexer.java:1602)
        at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:64)
        at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:52)
        at org.hibernate.boot.archive.internal.JarFileBasedArchiveDescriptor.visitArchive(JarFileBasedArchiveDescriptor.java:147)
        at org.hibernate.boot.archive.scan.spi.AbstractScannerImpl.scan(AbstractScannerImpl.java:48)
        at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:76)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:107)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:254)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:168)
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:52)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1847)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784)
        ... 17 more

build.gradle

dependencies {
// Comment these beam libraries to not see the error in shadow jar But i need this
    implementation 'org.apache.beam:beam-sdks-java-core:2.27.0' 
    implementation 'org.apache.beam:beam-runners-direct-java:2.27.0'
    implementation 'org.apache.beam:beam-runners-google-cloud-dataflow-java:2.27.0'
// ....other dependencies

} 
jar {
    manifest {
        attributes "Main-Class": "com.sample.orchestrator.OrchestratorApplication"
    }

    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

shadowJar {
    zip64 = true
    exclude "**/Log4j2Plugins.dat"
    // Required for Spring
    mergeServiceFiles()
    append 'META-INF/spring.handlers'
    append 'META-INF/spring.schemas'
    append 'META-INF/spring.tooling'
    transform(PropertiesFileTransformer) {
        paths = ['META-INF/spring.factories' ]
        mergeStrategy = "append"
    }
}

Here is the entity manager related beans.

@Configuration
@EnableJpaRepositories(basePackages = {
        "com.sample.orchestrator.database.elabs.repository" }, entityManagerFactoryRef = "elabsEntityManager", transactionManagerRef = "elabsTransactionManager")
@PropertySource("classpath:application-${spring.profiles.active}.yml")
public class ElabsDataSourceConfig {
    @Value("${spring.datasource-elabs.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource-elabs.url}")
    private String url;

    @Value("${spring.datasource-elabs.username}")
    private String username;

    @Value("${spring.datasource-elabs.password}")
    private String password;

    @Value("${spring.jpa.database-platform}")
    private String dialect;

    @Value("$(spring.jpa.hibernate.ddl-auto)")
    private String ddlAuto;

    @Value("$(spring.jpa.show-sql)")
    private String showSql;

    @Bean(name = "datasource-elabs")
    public DataSource datasourceElabs() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean("elabsEntityManager")
    public LocalContainerEntityManagerFactoryBean elabsEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(datasourceElabs());
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setPackagesToScan(new String[] { "com.sample.orchestrator.model.database.elabs" });
        // em.setPersistenceXmlLocation("classpath:persistence.xml");
        HashMap<String, Object> properties = new HashMap<>();
        properties.put("hibernate.dialect", dialect);
        properties.put("hibernate.ddl-auto", ddlAuto);
        properties.put("hibernate.show-sql", showSql);
        em.setJpaPropertyMap(properties);
        return em;
    }

    @Bean("elabsTransactionManager")
    public PlatformTransactionManager elabsTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(elabsEntityManager().getObject());
        return transactionManager;
    }
}

Here is a sample program.

To run please include

  • ./gradlew bootRun -Pdev
  • ./gradlew bootJar and include "-Dspring.profiles.active=dev" while running
  • ./gradlew shadowJar and include "-Dspring.profiles.active=dev" -- Error Step.

The reason I am not using bootJar, because I am creating a google dataflow pipeline with the application, the dependent jar files aren't staged from bootJar(Beam needs absolute path of dependencies to stage the relevant files). But I have tried with a non spring maven shaded jar, all the dependent files were staged. Hoping to achieve the same with spring shadowJar.

  • Instead of working around Spring Boot, I would try to get it to run with the Spring Boot plugin (maybe using a different layout? ). As this will inevitable fail again when upgrading to newer versions. There is probably a way to get a regular spring boot jar working in a Google Dataflow Pipeline (maybe the Spring Cloud people can help/advice?). – M. Deinum Feb 17 '21 at 07:28
  • I don't see anything related to Apache Beam in the error messages. Is there something that made you think that it is related to Beam? – Kenn Knowles Feb 17 '21 at 18:44
  • @KennKnowles When i comment out the beam libraries and create a shadowJar. I dont see bean creation exception on running it. – Raghu Dinka Vijaykumar Feb 17 '21 at 18:53
  • @KennKnowles i have provided a sample program, do check and let me know – Raghu Dinka Vijaykumar Feb 17 '21 at 18:56
  • I'm afraid I don't know anything about spring boot so I cannot guess. – Kenn Knowles Feb 17 '21 at 23:24

0 Answers0