IntelliJ Live Template Tip – Autowired Dependencies

Do you type these lines a lot?

@Autowired
private MyAwesomeService myAwesomeService;

Then try adding a Live Template to your IntelliJ settings that helps you reduce the number of keystrokes. Go to your Settings (Cmd+, on Mac or Ctrl+Alt+S on Windows) and find the Live Templates panel. On the right, select the ‘other’-group and click on the plus sign to add a new template.

Give the template a name (I chose auto and a description, then make sure it has a context of Java Declarations and the window looks somewhat like this:

live_template

Click ‘Edit Variables’ and make sure the TYPE variable has the expression set to expectedType() (this will open IntelliJ’s type completion box when the template activates). Then set the expression for VAR_NAME to suggesteVariableName() (this whill cause IntelliJ to suggest a name of the variable when you select the type).

template_vars

Now click Ok and close the Settings dialog. Go to your class file and at the place of an instance variable declaration, start typing auto and wait for the popup to show. Press Enter, type the name of your type and press Enter again, you should have a beautiful declaration.

–JH

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.

Returning Groovy’s GStringImpl in a Jersey endpoint

I started playing around with some technologies to try and increase my productivity when building RESTful APIs. The current setup I am using has Groovy, Spring 4, Jackson 2 and Jersey 2. The project is built by Gradle and runs on the Google AppEngine. A post describing the way this project was setup will follow shortly. I just wanted to share a little piece of code with the world first.

The above setup works nicely for JSON objects and HTML and things like that. I just ran into a little snag when I tried to get a little test running:

class ApiInfo {
    int count = 1;

    @GET
    hello() {
        "Hello world ${count}"
    }
}

This resulted in an Error 500, with the following problem as its cause:

SEVERE: MessageBodyWriter not found for media type=text/plain, type=class org.codehaus.groovy.runtime.GStringImpl, genericType=class java.lang.Object

At first it looks strange that a ‘normal’ String cannot be serialized to text/plain, until you realize you’re working with Groovy and Java’s String is final. So we apparently need a MessageBodyWriter to support this:

import groovy.json.internal.Charsets
import org.codehaus.groovy.runtime.GStringImpl

import javax.ws.rs.WebApplicationException
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.ext.MessageBodyWriter
import javax.ws.rs.ext.Provider
import java.lang.annotation.Annotation
import java.lang.reflect.Type

/**
 * Adds support for Groovy's GStringImpl as a Jersey output.
 * LICENSE: Do-whatever-you-want-but-attribution-would-be-appreciated.
 *
 * @author J.H. Kuperus (www.jhkuperus.nl)
 */
@Provider
class GStringImplMessageBodyWriter implements MessageBodyWriter< GStringImpl > {

    @Override
    boolean isWriteable(Class< ? > type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        GStringImpl.isAssignableFrom(type) && mediaType == MediaType.TEXT_PLAIN_TYPE;
    }

    @Override
    long getSize(GStringImpl gString, Class< ? > type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        gString.length()
    }

    @Override
    void writeTo(GStringImpl gString, Class< ? > type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap< String, Object > httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
        entityStream.write(gString.getBytes(Charset.forName('UTF-8')))
    }
}

Feel free to use this piece of code, send me remarks or correct any mistake(s) 😉

–JH

JavaFX : Centering Controls

Across the blogosphere, I found a post on how to center controls by using binding. The proposed method certainly works, but there is a catch.

When you are doing your layout by binding the layoutX and layoutY properties of your controls, you may experience a degradation of performance while resizing or scrolling. This will probably not be noticeable with only a handful of controls/shapes on screen. If however you start drawing hundreds of shapes/controls with this method, you will certainly see the slowdown. Let’s see why…

Continue reading

JavaFX Grid Component Worries

If you’re working with JavaFX, you will probably know these two truths:

  • The JFXtras library has some really awesome components
  • The JavaFX platform is trying out new controls in the preview packages

A good thing about this, is that the JavaFX team is taking the good stuff from the JFXtras library and putting it into the platform. A bad thing about it is you start to expect the preview controls have the same functionality as the JFXtras controls.

Continue reading

Moving Lines Around In JavaFX

Did you know, you can define ‘relative’ Lines in JavaFX? When you’re drawing complex visualizations, you sometimes want to have a Line that is horizontal and 10 pixels long, no matter what. No problem you say, just define its starting point as (x, y) and its end point as (x+10, y):

Line {
  startX: 40
  startY: 40
  endX: 50
  endY: 40
}

Sure, easy peasy. What if you want this Line to move around based on some variable’s value?Continue reading

Apple Mail And Outlook: Making Signatures Interoperable

Recently I switched from using Windows and Outlook at work to my brand-spankin’ new MacBook with Apple Mail. The first thing I ran into was getting replies to my emails that my signature was all borked.

After a long search I have finally been able to fix these so they look good in my colleagues’ Outlook. The problem lies with the editor in Apple Mail, somehow it just makes completely borked HTML that Outlook interprets differently.

The good news is that the solution is devilishly simple. Just follow these steps for each signature you want:

  • Create the signature in Apple Mail
  • Save the signature
  • Close Apple Mail
  • Open ~/Library/Mail/Signatures
  • Open one of the .webarchive files with TextEdit
  • Make the signature the way you want it in TextEdit
  • Save it and re-open Mail and you’re done!

Cheers!

–JH