An open API service indexing awesome lists of open source software.

https://github.com/thma/fmek

Emulating a jee 7 container with SpringBoot.
https://github.com/thma/fmek

Last synced: over 1 year ago
JSON representation

Emulating a jee 7 container with SpringBoot.

Awesome Lists containing this project

README

          

[![Build Status](https://travis-ci.org/thma/fmek.svg)](https://travis-ci.org/thma/fmek)
# fmek

Emulating a JEE 7 container with SpringBoot.
Highlights:
- unit testing of JEE components
- Providing a lightweight JEE 7 runtime container based on SpringBoot
- Developing Spring application with minimal code dependencies on Spring

> "The Fmeks are a diminutive sapient species native to the planet Fmoo, they are the sworn enemies of the Arquillians."
-- [aliens.wikia]

## Supported Features:

- JSR-330 'javax.inject.Inject' CDI Annotations
- JSR-299/318 'javax.interceptor.Interceptor' CDI Annotations (based on a patched version of springcdi https://github.com/nschlimm/spring-interceptor)
- JTA
- JPA
- JMS
- Message Driven Beans
- JAX-RS
- Servlets

## Not supported (and not planning to do so...):

- EJB Session Beans

## Use cases
- **unit testing of JEE components**
Unit testing JEE components can be quite a hazzle if you want to test across different software layers (without using mocks) or if you want to test container provided features like JTA transactions including two phase commit synchronizing different XA resources.

Typical solutions use specialized Junit Testrunners like CDI-Unit CdiRunner or the DeltaSpike CdiTestRunner which provide a Weld CDI container for unit tests. This is great for testing CDI dependency injection. But integrating JAX-RS or JTA with this approach is far from trivial.

The classical fullblown approach is to use tools like Arquillian which provide the complete JEE infrastructure to your junit tests. The downside with Arquillian is that the assembly of the container can be quite complex and tends to slow down the execution of the junit tests.

The **fmek** approach is simple: just provide all required JEE dependencies of your application by a SpringBoot Maven POM. The Junit test will be executed by the SpringJUnit4ClassRunner which sets up the Spring container serving all required components:

```java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {HelloWorldRestApplication.class,
EmulateJeeContainerConfiguration.class})
public class GreetingTests {

@Inject
private CountService countService;

@Inject
private GreetingCrudService greetingCrudService;

@Inject
private GreetingPostingService postingService;

private static final String template = "Hello, %s!";

@Test
@Transactional
public void testGreetings() throws JMSException {
createAndSaveAGreeting();
createAndSaveAGreeting();
createAndSaveAGreeting();

Greeting g = greetingCrudService.getGreeting(1);
assertNotNull(g);
assertEquals(1, g.getId());
assertEquals("Hello, user-1!", g.getContent());

List allGreetings = greetingCrudService.getAllGreetings();
assertEquals(3, allGreetings.size());
}

private void createAndSaveAGreeting() throws JMSException {
long id = countService.incrementAndGet();
Greeting greeting = new Greeting(id, String.format(template, "user-" + id));
greetingCrudService.store(greeting);
postingService.sendGreeting(greeting);
}

}
```

- **Providing a lightweight JEE 7 runtime container based on SpringBoot**
Of course a Spring container is not only useful in a testing environment but can also be used as a full-fledged deployment and runtime environment for production.

All you need is a main class that is annotated as @SpringBootApplication that starts up the Spring container by calling SpringApplication.run:
```java
@SpringBootApplication
public class HelloWorldRestApplication extends ResourceConfig {

public HelloWorldRestApplication() {
register(RequestContextFilter.class);
register(HelloWorldResource.class);
}

public static void main(String[] args) {
Object[] contextClasses = {HelloWorldRestApplication.class, EmulateJeeContainerConfiguration.class};
SpringApplication.run(contextClasses, args);
}
}

```

By calling mvn install this main class and all its dependencies are assembled to an executable jar. Thus no application deployment is needed.

You can even add extended support for application monitoring and managing by adding a dependency to Spring Boot Actuator in your POM File:


org.springframework.boot
spring-boot-starter-actuator

- **Developing Spring application with minimal code dependencies on Spring**
If you don't intend to deploy your application to a JEE container it still makes sense to minimize explicit Spring dependencies in your code. As an example have a look at the following service class which exclusively uses JEE standard APIs can be completely managed by Spring:
```java
package org.fmek.example.services;

import org.fmek.example.domain.Greeting;
import org.fmek.example.interceptors.Log;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
import java.util.List;

@Named
@Transactional
@Log
public class GreetingCrudService {

@Inject
private EntityManager entityManager;

public void store(Greeting g) {
entityManager.merge(g);
}

public List getAllGreetings() {
TypedQuery q = entityManager.createQuery("SELECT g FROM Greeting g", Greeting.class);
return q.getResultList();
}

public Greeting getGreeting(long id) {
return entityManager.find(Greeting.class, id);
}
}
```

## Docs:
http://thma.github.io/fmek/

[aliens.wikia]: http://aliens.wikia.com/wiki/Fmek