Spring Context Mix-Ups

While trying to add caching to a bean in my client’s project, I ran into some strange behaviour. The project already used caching on several components and used the @Cacheable annotation with an EhCache backing store. I added a cache definition to the ehcache.xml file and put the @Cacheable annotation on the method, recompiled, tested… No caching.

Update 2015-01-26: I added a little trick to mitigate this situation if you run into it. See below for the fix.

Confused, I cleaned, recompiled again, restarted, tested. Still no caching. My first instinct was: maybe caching is improperly configured and the other beans also have no active caching, even though we think they do. So I started debugging, to see if the calls to the other beans did use caching. To my surprise, they did. Refreshing the page did not cause those methods to be called again, but mine were.

Some further debugging showed that the SpringCacheAnnotationParser did process my bean and was able to see the @Cacheable annotation. However, when debugging the method that was supposed to be cached, I noticed there were no references to any CacheInterceptor instances in the stack trace. Even though during startup my bean was replaced by a generated proxy.

This raised a suspicion that maybe I was looking at two instances of my bean. A breakpoint on my bean’s constructor revealed that indeed, it was called twice. The cause became pretty obvious when I examined the Spring configuration files:

applicationContext.xml

<beans ...>
  ...
  <context:component-scan base-package="com.our.app"/>
  ...
</beans>
servlet-context.xml

<beans ...>
  ...
  <context:component-scan base-package="com.our.app"/>
  ...
</beans>

Aha! It appears our Spring context is loading all classes annotated with @Component, @Service, etc. twice! Once on the startup of the application and again when the first request comes in for the dispatcher servlet. Now, the reason that caching worked on some, but not all beans, lied in the fact that caching was configured in the applicationContext.xml file, which applied caching wrappers to all beans in that context. There was no caching configured in servlet-context.xml, causing beans loaded there to not have caching wrappers.

Our Java EE Servlet Filters were loaded from the application-context.xml, which contained caching. Those were fine. But any requests coming from the dispatcher servlet would reach beans in the servlet-context.xml context, which did not have caching.

The solution was quite a lot of work, since we had to re-evaluate all annotated classes and decide whether they should live in the application context, or the dispatcher servlet context. The rule of thumb we used here was:

Classes annotated with @Component and @Service will be loaded in the application context. Classes annotated with @Controller and its derivatives will be loaded in the dispatcher servlet context.

I realize there may be more subtle cases where this rule does not fully apply, but it’s a good starting point. Generally you want any potentially shared beans in the application context and anything specifically tied to the dispatcher servlet in its context. At least take this advice to heart:

Never, ever use component-scan on the same package tree from different contexts

Update 2015-01-26: If you have this same problem and are unable to move your controllers to a separate package tree, you can use a little configuration option of Spring’s component scan. You can use include and exclude filters to filter the @Controller annotations out of the application context and only include them in the servlet context. The snippet below filters out the controllers, you should use this in you application context:

<beans ...>
  ...
  <context:component-scan base-package="com.our.app">
    <:context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
  </context:component-scan>
  ...
</beans>

The same with annotations:

@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)})
@Configuration
public class MyConfiguration {}

Then reverse the filter on the servlet-config and you have separated your stereotypes. Note that I believe this is more of a hack than a sound application architecture, but in legacy applications you may not have much of a choice…

–JH

PS: This post talks about @Cacheable, but the same behaviour might be triggered by things like @Transaction and other bean post processing features in a context.

Is Spring Boot rebooting Spring’s Ease of Use?

Spring started out as a ‘small’ Dependency Injection container, which gave the Java world a whole new direction. Especially on the area of Java Enterprise, it offered innovations which allowed for faster and easier development of new Java applications.

In the last few years, Spring has grown enormously as a framework. The basics are still relatively simple, but due to the large number of different extensions it can be hard to start a new project. The people at Spring are familiar with this situation and are trying to remedy it with its newest addition: Spring Boot.

Continue reading

Using Apache CXF to connect to Microsoft Dynamics

A few weeks back a friend of mine approached me with a request. His client was building an application which was supposed to connect to their Microsoft Dynamics CRM. However, they were unable to get any decent response from the CRM Server and needed a little help. My friend and I took up the task of digging into this and solved it, using the Apache CXF framework (which the client was using). In this post, we will explain how to do this. (If you’re just looking for the solution, jump straight down)

Update 17-06-2014: Marnix Klooster used the stuff from this post and elaborated on it over at stackoverflow. Could be a good next step if the stuff below doesn’t help you.

WSDL Analysis & Authentication

The strange thing was that the web service seemed to not respond at all, to any sort of SOAP request, whether faulty or correct. This appears to be Microsoft’s way of saying ‘Hey, you need to authenticate before you can ask me anything’. Not really standard, but I guess we have to live with it.

The documentation of these services leave some things to wish for, so we were forced to delve through the WSDLs and use SoapUI to throw a lot of requests at the services. Eventually the STS authentication service replied with a valid security token. But, Apache CXF seemed to be unable to handle this response. Analysis of the response showed that Microsoft returns an encrypted SAML token, instead of a publicly readable one. Apache CXF is only just able to handle this (see issue CXF-4357), so it takes a snapshot build to authenticate which has been fixed in the 2.6.2 release.

The solution

The solution itself is actually surprisingly simple. The most important part is having the most recent versions of the CXF libraries. The XML-fragment below shows the dependencies required for a Maven project. If you don’t use maven, download these libraries from Apache.

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>2.6.2</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>2.6.2</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-ws-security</artifactId>
    <version>2.6.2</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-ws-policy</artifactId>
    <version>2.6.2</version>
</dependency>

Most of the ‘magic’ happens in the Spring application context. In the following fragment, we glue together a JAX-WS client for the SOAP service and an STSClient which will take care of obtaining the SAML tokens. The context also includes a policy object telling the CXF framework that Microsoft’s extensions on the WS-Security policy can be ignored. Without this little piece, CXF will reject the configuration, because it cannot parse those policies. Let’s have a look:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xmlns:cxf="http://cxf.apache.org/core"
  xmlns:policy="http://cxf.apache.org/policy"
  xmlns:security="http://cxf.apache.org/configuration/security"
  xmlns:http="http://cxf.apache.org/transports/http/configuration"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  
  <jaxws:client name="{http://schemas.microsoft.com/xrm/2011/Contracts}CustomBinding_IOrganizationService" createdFromAPI="true">
    <jaxws:properties>
      <entry key="ws-security.sts.client"  value-ref="crm.sts-client" />
    </jaxws:properties>
  </jaxws:client>
  
  <bean name="crm.sts-client"  class="org.apache.cxf.ws.security.trust.STSClient">
    <constructor-arg ref="cxf"/>
    <property name="wsdlLocation" value="https://adfs.example.com/adfs/services/trust/mex"/>
    <property name="serviceName"  value="{http://schemas.microsoft.com/ws/2008/06/identity/securitytokenservice}SecurityTokenService"/>
    <property name="endpointName"  value="{http://schemas.microsoft.com/ws/2008/06/identity/securitytokenservice}UserNameWSTrustBinding_IWSTrust13Async"/>
    <property name="properties">
      <map>
        <entry key="ws-security.username" value="user1"/>
        <entry key="ws-security.callback-handler" value="net.quies.demo.sts.HardcodedPassword"/>
      </map>
    </property>
  </bean>
  
  <!-- Skip Microsoft extensions -->
  <bean class="org.apache.cxf.ws.policy.IgnorablePolicyInterceptorProvider">
    <constructor-arg>
      <list>
        <bean class="javax.xml.namespace.QName">
          <constructor-arg value="http://schemas.microsoft.com/xrm/2011/Contracts/Services"/>
          <constructor-arg value="AuthenticationPolicy"/>
        </bean>
      </list>
    </constructor-arg>
  </bean>
  
  <cxf:bus>
    <cxf:features>
    <!-- Enables policy support: -->
    <policy:policies/>
    <!-- Enables logging of SOAP messages. -->
    <cxf:logging/>
    </cxf:features>
  </cxf:bus>

</beans>

Note that the crm.sts-client bean contains the key information about the actual services invoked. The WSDL location, service name, endpoint and the username and password. These are all settings you should adjust to your particular environment. Note that it also references a class called HardcodedPassword, which is a very simple and insecure implementation of a CallbackHandler, providing CXF with the password:

public class HardcodedPassword implements CallbackHandler {
  @Override
  public void handle(Callback[] callbacks)
      throws IOException, UnsupportedCallbackException {
    for (Callback c : callbacks) {
      if (c instanceof WSPasswordCallback) {
        WSPasswordCallback passwordCallback = (WSPasswordCallback) c;
        passwordCallback.setPassword("passw0rd");
        continue;
      }
      throw new UnsupportedCallbackException(c);
    }
  }
}

Bringing it all together

With these beans setup, you’re ready to use the XRMServices in your code. Below is a little unit test to demonstrate how you can now create a CXF bus from the Spring context, create a service from it and call the port:

@Test
public void authenticate() throws Exception {
  URL wsdlLocation = new URL("https://xrmservices.exmple.com/XRMServices/2011/Organization.svc?wsdl");
  URL springLocation = new URL("classpath:applicationContext.xml");
  
  SpringBusFactory factory = new SpringBusFactory();
  Bus bus = factory.createBus(springLocation);
  BusFactory.setDefaultBus(bus);
  
  OrganizationService service = new OrganizationService(wsdlLocation);
  IOrganizationService port = service.getPort(IOrganizationService.class);
  
  Entity entity = new Entity();
  port.create(entity);
}

And that’s it. Calling the OrganizationService will now cause the CXF framework to first call the Token service to authenticate itself, obtain a token and use that as a SAML assertion in the resulting SOAP call. Heck, any service you now create from the Bus and that requires SAML authentication, will use the same setup transparently.

Happy coding!

–JH

Special thanks go out to Pascal de Kloe, from Quies.net.

Spring hand in hand with Swing Application Framework

Starting work on a new application is always a fun period. You get to choose all your frameworks from scratch and you are not limited by any previous mistakes (or decisions, as some call them). For this particular project I had to come up with an architecture that would support a graphical interface, easy configuration and potentially swapping components in and out.

The configuration requirement and the need to be able to swap components naturally made me choose Spring. Using dependency injection and Spring’s easy PropertyPlaceholderConfigurer, these requirements are easily met.

For the interface, I decided to give the Swing Application Framework (JSR 296) a go. The Swing Application Framework (SWAF from now on) is an attempt at making life with Swing a lot easier. It provides the developer with an application lifecycle, easy component configuration, simplified long-running tasks and many more simplifications. The reference implementation can be found at https://appframework.dev.java.net/.

Continue reading

Easy Event-Driven Application With Spring!

Suppose you are making an event-driven application. You have your listener interfaces and your event-generating objects. What is the most annoying part of getting this all to work?

Connecting your listeners to the event-generating objects. Every time you want some object to receive certain events, you have to register your listener with the correct producer object. This has some nasty effects on your code:

  • Either your listeners know to which object they are subscribing, or your event generators know who should be listening to their events
  • Due to this coupling, listeners and producers are difficult to test
  • Adding a new listener to your project requires some boilerplate code to get it working

Spring has a feature that can take care of all of this hassle: autowiring. For normal dependency injection, autowiring feels icky. It’s just too magical and leaves me with a feeling I am not in control. The great thing about autowiring is that it can be used on a per-method base.

Continue reading

SpringSource Application Platform – My Holy Grail

The SpringSource Application Platform has been in beta for some time now. In my rare free time I have been playing with it’s amazing set of features. Now that the platform is nearing its final release I want to share some of my thoughts about it.

I have been a fan of modular design even before I switched to my first Object Oriented Language. Although languages like Visual Basic, C++ and Java provide you with the means of building modular software, none ever enforce it. No matter how strict I design modules in my application, they somehow always get tangled up in each other.

Continue reading