Mark Little on Java EE and Microservices in 2016

Mark Little has an interesting article on InfoQ looking at what’s going on with Java EE and microservices. At the beginning of this year I looked at a number of Java frameworks that are emerging that support microservice development and deployment. What’s interesting is everyone has a slightly different take on what parts of the EE apis they would take with them, and/or how a Java based microservice should be packaged and deployed.

What I find interesting is there’s obviously a general agreement that there’s still parts of EE that are beneficial and useful for microservice development and deployment, but from a distance the activity in this space looks like vultures picking apart the carcass of Java EE.

While there’s still benefit for some to develop monolithic enterprise systems using Java EE and traditional app servers ‘in the traditional way’ as we have done for for the past 15 years or so, it’s interesting that microservices seems to be questioning the EE approach of all your apis in a bucket provided by a single app server. I rather like the JBoss Swarm approach of being able to pick the apis you want and just bundle/deploy a fat War with what you need. I wonder if there’s enough interest and/or momentum in this space that we might see EE (probably too late for EE8, but EE9?) start to embrace this different approach to building apps as many smaller, individual services, and directly offer support for microservices type approach in future EE versions?

Updating the endpoint URL for a generated JAX-WS client

When you generate a JAX-WS client from a locally deployed service, the URL for the endpoint and the WSDL are hardcoded into the generated client code. If you redeploy the service elsewhere (i.e. moving from a local development environment to a test or production environment), then you could regenerate against the new URL for the service, but the JAX-WS api does allow you to programmatically specify the endpoint and wsdl locations.

From this post, the key is to use the BindingProvider to specify a new value for BindingProvider.ENDPOINT_ADDRESS_PROPERTY:

BindingProvider bp = (BindingProvider)port;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://your_url/ws/sample");

By itself though, this gave me an additional exception as it appears the client it still attempting to locate the WSDL. To work around this, you can also pass the new WSDL url location when you instantiate the generated client (this is discussed here). Before using the BindingProvider snippet above, pass the updated urls into the client like this:

EndpointService service = new EndpointService(
    new URL("http://your-url-to-endpoint/Endpoint?wsdl"),
    new QName("http://namespace-of-endpoint-from-wsdl/",
						"EndpointService"));

SpotCollectorEndpoint endpoint = service.getSpotCollectorEndpointPort();

 

Core Spring – continued (2) – SpEL, Annotation based bean defs, Java-based configuration

Spring Expression Language (SpEL) introduced in Spring 3.0 introduces EL style language for referencing beans and properties, and gives a standard syntax for doing property replacement into beans.

Annotation based bean definition

  • component scan allows you to configure annotated beans – simplest approach, avoids xml:

Enabled with context:component-scan in xml file:

<context:component-scan base-package="your.package"/>
  • @Component – declares beans
  • @Autowired – bean of a matching type is automatically injected into contructor, method, or field
  • Only one constructor can be autowired, but multiple methods and attributes can be autowired
  • @Autowired properties don’t need setters
  • @Autowired methods don’t need to be setters, and don’t need to be named ‘set…()’
  • @Qualifier allows you to specify a specific bean id if matching beans by type is ambiguous

‘The spirit of autowiring is by type’ – use of the @Qualifier should be only if necessary, since it restricts the flexibility and power of the Autowiring.

Use of @Autowired implies @Required (don’t need to explicitly defined @Required if @Autowired)

Stereotype annotations

Also enabled via context:component-scan

  • @Service – indicates purpose in layering, but doesn’t add any additional behavior

Following stereotypes do add extra behavior:

  • @Repository – data access
  • @Controller – MVC controller
  • @Configuration – programmatic Spring configuration

Other Spring projects use similar annotation approach for adding additional stereotype based functionality.

JSR 330 CDI Annotation Support

  • Spring is a an implementation of JSR330
  • provides support for JSR330 standard @Named, @Inject, @Scope, @Singleton
  • Spring provides other Spring specific annotations not supported in JSR330 (@Value, @Required, @Lazy)

Bean configuration using Annotations & Java: @Configuration

  • Enabled with context:component-scan
  • @Configuration marks configuration clas
  • Use @Bean on method that provides instance of the bean
  • Method name is the id of the bean, eg participantService() – id = “participantService”
  • Java code can perform any initialization – you can invoke any other methods necessary to perform initialization
  • All @Bean annotated methods produce singletons by default – @Bean methods are proxied to add this behavior – this can be overridden with @Scope(“prototype”)
  • @Import allows to import other @Configuration classes
  • Alternate configuration: AnnotationConfigApplicationContext – instantiating this context allows a completely xml free configuration approach

 

Annotations vs XML based configuration

  • easier to make changes to annotated beans during development
  • could always move to xml config when beans become more mature, but no compelling reason to do this, could always just leave the annotations
  • xml config always overrides the annotation metadata

Spring JUnit Support
Integration testing support allows testing with Spring Bean dependencies

@ContextConfuguration("example-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class ExampleTest
{
    @Autowired
    private ExampleService exampleService;

    @Test
    public void eampleTest() { ... }
}