Posts

Showing posts from 2014

Including Java agent in standalone Spring Boot application

Recently at DevSKiller.com we've decided to move majority of our stuff to simple containers. It was pretty easy due to use of Spring Boot uber-jars, but the problem was in NewRelic agents which should have to be included separately. That caused uncomfortable situation so we decided to solve it by including NewRelic agent into our uber-jar applications. If you also want to simplify your life please follow provided instructions :)

At first we have to add proper dependency into our pom.xml descriptor:
<dependency> <groupiId>com.newrelic.agent.java<<groupId> <artifactId>newrelic-agent</artifactId> <version>3.12.1</version> <scope>provided</scope> </dependency>

Need micro caching? Memoization to the rescue

Caching solves wide sort of performance problems. There are many ways to integrate caching into our applications. For example when we use Spring there is easy to use @Cacheable support. Quite easy but we still have to configure cache manager, cache regions, etc. Sometimes it's unfortunately like taking a sledgehammer to crack a nut. So what can we do to "go lighter"?

There is a technique called memoization. Technically it's as easy as pie but true genius lies in simplicity. Model solution looks as follows:
public Foo getValue() { if (storedValue == null) { storedValue = retrieveFoo(); } return storedValue; } As you can see there is no problem in implementing it manually, but as long as we remember about DRY rule we can use already implemented solutions which additionally provides thread safety. Pretty good idea is to use Guava library.
// create Supplier<Foo> memoizer = Suppliers.memoize(this::retrieveFoo); // and use Foo variable = memoizer.get(); Som…

Runtime commited heap resizing

New day, new version of Java... nice :)

We used to update minor Java versions mostly due to security issues. But sometimes those minor updates brings us brand new, awesome features. So was for example with 7u40 which brought us awesome Mission Control known from JRockit. (If you are interested in tracking changes across Java updates take a look at
http://www.oracle.com/technetwork/java/javase/8all-relnotes-2226344.html for Java 8 or http://www.java.com/en/download/faq/release_changes.xml for Java 7)

Same situation is now with versions 7u60 and 8u20. Since now flags MinHeapFreeRatio and MaxHeapFreeRatio became manageable, which means we can change its values... in runtime :)

Debugging OpenJDK

Image
Sometimes debugging Java code is not enough and we need to step over the
native part of Java. I spent some time to achieve proper state of my JDK to do that, so short description probably will be useful for ones starting their trip. I'll use the brand new OpenJDK 9!

At first you have to obtain main repository by typing
hg clone http://hg.openjdk.java.net/jdk9/jdk9 openjdk9 Then in the openjdk9 directory type
bash get_source.sh That will download all sources to you local filesystem.

Theoretically compiling openjdk is not a big deal, but there are some (hmmm....) strange behaviours if you want to use it for debugging.

Managing Spring Boot application

Spring Boot is a brand new application framework from Spring. It allows fabulously quick development and rapid prototyping (even including CLI). One of its main features is to work from single "uber jar" file. By "uber jar" I mean that all dependencies, even an application server like Tomcat or Jetty are packed into a single file. In that we can start web application by typing
java -jar application.jar The only thing we're missing is the managing script. And now I want to dive into that topic.

Of course to do anything more than starting our application we need to know its PID. Spring Boot has a solution named ApplicationPidListener. To use it we need to tell SpringApplication we want to include this listener. And there are to ways to achieve that.

Spring Java Config 101

After my last article there were some questions about how Java configuration work in details, and we can extend it to suite our needs. So I'll try to answer those question in this post :)

Heart of Spring java configuration mechanism are @Configuration classes. That's the place where we can define all properties of our Spring context.

Assuming that we lean our application on annotations (which should be true if we want to use java config) we create beans using @Component annotation (with derivatives like @Repository, @Service and @Controller). Varying annotations apply for different layers:

@Componentgeneric for any compoenents@Repositorypersistence layer@Serviceservice layer@Controllerpresentation layer

Understanding Spring Web Initialization

Few years ago majority of us were used to write XML config files everywhere, to setup even simple Java EE application. Today using Java or Groovy to configure projects is becoming preferred way - you just need to take a look at Gradle or functionalities introduced in further versions of the Spring Framework to gen up on this.

Now I'll deal with configuring Spring contexts for web application.

Java EE provides ServletContainerInitializer interface, which allows libraries to be notified of a web application startup. Since Spring 3.1 we have SpringServletContainerInitializer class which handles WebApplicationInitializer by instantiating all found classes implementing this interface, sorting them basing on @Order annotation (non-annotated classes gets the highest possible order, so they are processed at the end) and invoking onStartup() method.

Spring integration testing with Spock

I'm currently working on a project where we use Spring Framework 4.0 and Spock for testing. Unit testing in Spock is really great, but there are some lacks in integration testing - especially in mocking Spring beans. Our requirement is to start up Spring context but with particular bean replaced with mock.

The easiest part we had do implement is just regular Spring test specification:

@ContextConfiguration( classes = [GatewayConfig, PaymentServiceConfig]) class PaymentServiceSpecIT extends Specification { final String CLIENT_ID = "54321" @Inject PaymentService paymentService def "Should return auth token"() { when: def token = paymentService.getAuthToken(CLIENT_ID) then: token } }