0


I am working on a prototype for using Spring Boot in our project. We have a JBoss server in production and I was thinking of running integration tests against Undertow embedded server using an embedded transaction manager like Atomikos, because a persistence.xml exists that I have to reuse. My test app context file has the following lines:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@EnableAutoConfiguration
@IntegrationTest("server.port:0")
@ActiveProfiles("test")
public abstract class TestApplicationContext  {
...
}

I have also added a custom test configuration as:

@Configuration
public class TestConfiguration {
    @Value("${spring.jpa.hibernate.dialect}")
    private String dialectClassName;

    @Value("${spring.jpa.hibernate.transaction.manager_lookup_class}")
    private String transactionManagerClass;

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        return new UndertowEmbeddedServletContainerFactory(9000);  // Don't know if this can be avoided using some properties
    }

    @Bean
    @ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
    public DataSource dataSource() throws Exception {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                       DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean =
                builder.dataSource(dataSource).persistenceUnit("main").build();
        Properties additionalProperties = new Properties();
        additionalProperties.put("hibernate.dialect", dialectClassName);
        additionalProperties.put("hibernate.transaction.manager_lookup_class", transactionManagerClass);
        entityManagerFactoryBean.setJpaProperties(additionalProperties);
        return entityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        // this should not be needed if I have included Atomikos but it seems to pick 
        // JPA Transaction manager still and fails with the famous NullPointerException at
        // CMTTransaction class - because it cannot find a JTA environment
        // return new JtaTransactionManager(userTransaction, transactionManager);
    }
}

My gradle include for Atomikos is:

testCompile('org.springframework.boot:spring-boot-starter-jta-atomikos')

I am using Spring Boot 1.2.0-RC2.

CAn someone point out what I am doing wrong or how to solve this?

Thanks,
Paddy

Paddy
  • 3,472
  • 5
  • 29
  • 48
  • First I would upgrade to the final 1.2.0 release of Spring Boot next your `@EnableAutoConfiguration` should be on your configuration class currently it doesn't do anything. – M. Deinum Dec 17 '14 at 07:43
  • Hi @Deinum, this is where I am confused quite a bit trying to understand Spring Boot. With older versions of Spring (atleast on projects that I have been part of), we used to have an abstract test context annotated with SpringJUnit4ClassRunner that did not have any tests but which other tests extend. I do not want TestApplicationContext to have any tests but just readily bootstrapped base for running tests. If my mark TestApplicationContext itself with "@configuration" and remove TestConfiguration class, my "@Bean" declarations are not getting executed. Can you kindly explain the concept here? – Paddy Dec 17 '14 at 08:07
  • The test runner is just that a test runner it isn't configuration, you are trying to mix things into a single class. – M. Deinum Dec 17 '14 at 08:28
  • Hi @Deinum, I do not want my main app to run in an embedded container, so I specify "@EnableAutoConfguration" with exclude in main app, but want my tests to use embedded, so I specify this annotation. But if I move it to TestConfiguration, my Undertow server is not even starting, also it is not solving the JTA problem (same stack trace. I have only "@RunWith", "@SpringApplicationConfiguration", "@WebApplicationConfiguration" and "@ActiveProfies" in the TestApplicationContext, I have moved "@EnableAutoConfiguration" and "@EnableTransactionManagement" to TestConfiguration, but no luck. – Paddy Dec 17 '14 at 08:47
  • You don't need `@EnableTransactionManagement` as that is automatically done by Spring Boot. Also it looks to me as if you try to configure to much and try to work around spring boot in your test configuration. You should just be able to create an application class (not configuration) with a main for local testing/running and also have it extend `SpringBootApplicationInitializer` for deployment. The first will start an embedded container, the second is for deploying to a server. – M. Deinum Dec 17 '14 at 08:51
  • I did what you suggested (I hope you meant SpringBootServletInitializer as I could not find the class you specified). Undertow is working even if I made it test-compile dependency, but not Atomikos, what could be the reason. I get the same stack trace of NullPointerException (not being able to find JTA). Should I really make Atomikos compile dependency instead of test-compile dependency? – Paddy Dec 17 '14 at 10:12
  • You should not need to specify the transaction manager and the `LocalContainerEntityManagerFactoryBean`. Those should be configured by spring. If I recall atomikos has its own `transaction.manager_lookup_class` instead of the default CMT based one. This will be auto configured by Spring Boot. Have you tried removing the specific bean? – M. Deinum Dec 17 '14 at 12:29
  • The same goes for the datasource. You can specify in your `application.properties` in the `src/test/resources` directory which driver etc. to use this will override the ones in the default `application.properties`, or add an `application-test.properties` for this specific case. So I'm basically saying you can drop the `TestConfiguration ` and just use Spring Boot. – M. Deinum Dec 17 '14 at 12:34
  • Hi @Deinum, I removed the TestConfiguration class and used SpringBootServletInitializer (I guess I could not find SpringBootApplicationInitializer). Actually I got the clue from one Jboss developer forum that you have to specify a property "hibernate.transaction.jta.platform". We were already having one hibernate.properties in classpath. So i created two hibernate.properties to override the default, in src/main/resources and in src/test/resources. In the latter, I set the value to BitronixJTAPlatform class FQ name and it seems to have crossed that stage. Thanks a lot for helping me out. – Paddy Dec 17 '14 at 13:08
  • Don't do that as that interferes with the Spring Boot auto configuration. Remove the hibernate.properties and especially the `hibernate.transaction.jta.platform` property as that is being set by Spring Boot. Also if you really want to set additional properties use the `application.properties` and add a `spring.jpa.properties.name.of.hibernate.property` with a value to it. You currently have competing configuration mechanisms. As I mentioned earlier you try to do to much and make it that way to complex. – M. Deinum Dec 17 '14 at 15:51

0 Answers0