Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

I’m used to writing JUnit test classes with my Spring classes. I was working on some very old code that had no Spring at all. It was just a normal class that needed to be tested. I didn’t include any of the annotations that I normally have at the top of a class, but IntelliJ couldn’t see them. When I ran the class with Maven, it did run the tests, but also ran the tests annotated with @Ignore. What the heck. I had to do some digging and saw that you need to add a @RunWith to the class declaration.

@RunWith(BlockJUnit4ClassRunner.class)
public class W2GPdfTest {
    // normal test methods
}

Problem solved.

December 17th, 2015

Posted In: Java, java ninja, Javaninja, JUnit

Leave a Comment

A common logging configuration is a log file per day. Building off of Logback Configuration File Change, let’s determine what it would take to also add a daily rolling file. How do you do this with logback?

In this example, I turned on the automatic scanning of the logback configuration file and set it to check every 5 minutes. This is a good compromise between being able to change the logging configuration on the file and also preventing increased load on the production file system.

I also created several variables to make customizing the configuration to individual developers workstation’s easy.

In this example, I used a TimeBasedRollingAppender to roll the file once per day. Logback keeps 30 days of files around and doesn’t use compression. To enable compression, change the fileNamePattern inside the rollingPolicy to end in .gz or .zip instead of .log.

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="5 minutes">

    <property name="contextName" value="bonus-services"/>
    <!--
        The directory that the log files will be created in.  If the directory does not exist, Logback will give an
        error.  Logback will continue to log to the console, but there will be no log created.  Some developers will
        prefer this way so that they can see the files in the console, but don't have to worry about them on their local
        machines.

        To create a symbolic link (/opt/tomcat) to your actual tomcat installation:
        sudo ln -s ~/apache-tomcat-8.0.28 /opt/tomcat
    -->
    <property name="loggingDir" value="/opt/tomcat/logs"/>
    <property name="encoderPattern"
              value="%d{HH:mm:ss.SSS}|%-5level|${HOSTNAME}|${contextName}|%msg ||%class:%line %xException{full} %n"/>


    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder>
            <pattern>${encoderPattern}</pattern>
        </encoder>
    </appender>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${loggingDir}/${contextName}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>${contextName}.%d{yyyy-MM-dd}.log</fileNamePattern>

            <!-- keep 30 days' worth of history -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <encoder>
            <pattern>${encoderPattern}</pattern>
        </encoder>
    </appender>

    <logger name="com.cdi" level="INFO"/>
    <!-- Show info on rest calls -->
    <logger name="org.springframework.web.client" level="DEBUG"/>
    <logger name="org.springframework.http.converter" level="DEBUG"/>

    <root level="WARN">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

December 15th, 2015

Posted In: java ninja, Javaninja, logback

Leave a Comment

Springframework beans don’t play well with static methods. It’s always a pain when you have a static method that needs Spring injection. I had a static class with static initializer that loaded data from a properties file, that was then accessed via static methods for each property. I needed to move away from the properties file and towards retrieving the data from the database from another bean that was a Spring bean.

The static class was PropertyUtil. The spring bean that retrieved the data from the database from PropertiesBean.

To make this work, I made the following changes:

  • @Component – This was added to the class to make it into a Spring-bean
  • Added an @Autowired property for PropertiesBean – This makes the PropertiesBean available by Spring-injection
  • Added a static PropertiesBean – This will be used to be bridge between the instance bean and the static property
  • Removed static from init and added @PostConstruct – This means that the method will be executed after the bean is constructed, but before the bean is placed into service

The flow for the bean’s creation was as followed. It was instantiated like a regular spring bean. The @Autowired properties are injected, then the @PostConstruct method is executed. That method then copied the reference from the injected bean to the static reference to make it available via static methods/properties.

This is what the final code looked like:

@Component
public class PropertyUtil {

    private static PropertiesBean propertiesBeanStatic;

    @Autowired
    private PropertiesBean propertiesBean;

    public static myValue = null;

    @PostConstruct
    public void init(){
        propertiesBeanStatic = propertiesBean;
        myValue = propertiesBeanStatic.getProperty("myProperty")));		     
    }
}

December 15th, 2015

Posted In: Java, java ninja, Javaninja, Spring

Tags:

Leave a Comment

We had a need to submit request header information on every request to a specified system when we submit a REST call. We used the Springframework RestTemplate to perform our REST call. The RestTemplate provides a nice, easy way to modify all outbound requests via the ClientHttpRequestInterceptor interface.

The contents of the interceptor is:

package com.javaninja.core.spring;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;

/**
 * Interceptor for the Rest calls.  The interceptor adds the System-Key that is required in order to authenticate.
 */
public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
	private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("#{properties.systemKey}")
	private String systemKey;

	/**
	 * The interceptor adds the SYSTEM-Key that they are looking for on their end.
	 *
	 * Intercept the given request, and return a response. The given {@link ClientHttpRequestExecution} allows the
	 * interceptor to pass on the request and response to the next entity in the chain.
	 * <p>
	 * <p>A typical implementation of this method would follow the following pattern:
	 * <ol>
	 *     <li>Examine the {@linkplain HttpRequest request} and body</li>
	 *     <li>Optionally {@linkplain org.springframework.http.client.support.HttpRequestWrapper wrap} the request to filter HTTP attributes.</li>
	 *     <li>Optionally modify the body of the request.</li>
	 * 	   <li><strong>Either</strong>
	 * 	   <ul>
	 * 	       <li>execute the request using {@link ClientHttpRequestExecution#execute(HttpRequest, byte[])},</li>
	 * 	       <strong>or</strong>
	 * 	       <li>do not execute the request to block the execution altogether.</li>
	 * 	   </ul>
	 * 	   <li>Optionally wrap the response to filter HTTP attributes.</li>
	 * </ol>
	 * @param request   the request, containing method, URI, and headers
	 * @param body      the body of the request
	 * @param execution the request execution
	 * @return the response
	 * @throws IOException in case of I/O errors
	 */
	@Override
	public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
	throws IOException {
		HttpHeaders headers = request.getHeaders();
		logger.debug("System-Key : {}", systemKey);
		headers.add("System-Key", systemKey);
		return execution.execute(request, body);
	}
}

Configuring the interceptor is fairly easy. It involves two steps. The first step is to declare the list of interceptors.

    <util:list id="interceptors">
          <bean id="vendorRestTemplateInterceptor" class="com.javaninja.core.spring.RestTemplateInterceptor"/>
    </util:list>

The next step is to associate the interceptors with the desired RestTemplate.

    <bean id="vendorRestTemplate" class="org.springframework.web.client.RestTemplate"
         p:interceptors-ref="interceptors"/>

Once you have that, you can use the RestTemplate as you normally would. Every outgoing request will have the basic authorization header added to the request automatically. As a note, in that application, we had a RestTemplate with an interceptor that was used to communicate with the vendor and another RestTemplate that did not have an interceptor that was used to communicate with an internal system.

December 9th, 2015

Posted In: Java, java ninja, Javaninja, Spring

Tags: , , , , , , ,

Leave a Comment

We’ve all been there. Hot deploys are so convenient, but they consume memory via ClassLoader leakage. You eventually run out of memory and your server dies.

java.lang.OutOfMemoryError: PermGen space

Tomcat leak prevention

Tomcat helped us a lot when it came out with it’s memory leak prevention. This has been our mainstay tool since Tomcat 6. At times, even this wasn’t enough to prevent dreaded permgen errors. http://wiki.apache.org/tomcat/MemoryLeakProtection

We have all seen a log message similar to the following, thanks to Tomcat:

02-Dec-2015 14:50:41.197 WARNING [RMI TCP Connection(6)-127.0.0.1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [bonus-services] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

Java 8 says goodbye to PermGen

Java 8 helped a lot by removing the limits of permgen by opening up all of the meta space. This wasn’t as much a fix as it was to make the memory container much larger. Even this has it’s limits.

java.lang.OutOfMemoryError: Metadata space

Mattias Jiderhamn’s ClassLoader Leak Prevention library

Enter the https://github.com/mjiderhamn/classloader-leak-prevention library. This does many of the things that Tomcat does along with some others. It’s uses an Apache 2 license. There is a Servlet Context Listener that listens for the context creation and context destruction. This allows it to perform it’s work, all for your benefit.

It is very easy to integrate into your webapp. The first step is to add the Maven dependency.

<dependency>
    <groupId>se.jiderhamn</groupId>
    <artifactId>classloader-leak-prevention</artifactId>
    <version>1.15.2</version>
</dependency>

Then you need to add the listener as the first listener in your web.xml.

<listener>
    <description>https://github.com/mjiderhamn/classloader-leak-prevention</description>
    <listener-class>se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor</listener-class>
</listener>

When your webapp starts up, you will see the following as logging:

ClassLoaderLeakPreventor: Settings for se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor (CL: 0xcb6c98f):
ClassLoaderLeakPreventor:   stopThreads = true
ClassLoaderLeakPreventor:   stopTimerThreads = true
ClassLoaderLeakPreventor:   executeShutdownHooks = true
ClassLoaderLeakPreventor:   threadWaitMs = 5000 ms
ClassLoaderLeakPreventor:   shutdownHookWaitMs = 10000 ms
ClassLoaderLeakPreventor: Initializing context by loading some known offenders with system classloader

When you hot deploy your webapp, you will see logging similar to the following:

ClassLoaderLeakPreventor: se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor shutting down context by removing known leaks (CL: 0xcb6c98f)
ClassLoaderLeakPreventor: Looping 5 RMI Targets to find leaks
ClassLoaderLeakPreventor: Looping 5 RMI Targets to find leaks
ClassLoaderLeakPreventor: Internal registry of java.beans.PropertyEditorManager not found
ClassLoaderLeakPreventor: Custom ThreadLocal of type org.springframework.core.NamedThreadLocal: Prototype beans currently in creation with value null will be made stale for later expunging from Thread[http-nio-8080-exec-1,5,main]
ClassLoaderLeakPreventor: Custom ThreadLocal of type org.springframework.core.NamedThreadLocal: Transactional resources with value null will be made stale for later expunging from Thread[http-nio-8080-exec-1,5,main]
ClassLoaderLeakPreventor: Custom ThreadLocal of type org.springframework.core.NamedThreadLocal: Transaction synchronizations with value null will be made stale for later expunging from Thread[http-nio-8080-exec-1,5,main]
ClassLoaderLeakPreventor: Custom ThreadLocal of type org.springframework.core.NamedThreadLocal: Prototype beans currently in creation with value null will be made stale for later expunging from Thread[http-nio-8080-exec-1,5,main]
ClassLoaderLeakPreventor: Custom ThreadLocal of type org.springframework.core.NamedThreadLocal: Transactional resources with value null will be made stale for later expunging from Thread[RMI TCP Connection(idle),5,RMI Runtime]
ClassLoaderLeakPreventor: Custom ThreadLocal of type org.springframework.core.NamedThreadLocal: Transaction synchronizations with value null will be made stale for later expunging from Thread[RMI TCP Connection(idle),5,RMI Runtime]
ClassLoaderLeakPreventor: Custom ThreadLocal of type org.springframework.core.NamedThreadLocal: Prototype beans currently in creation with value null will be made stale for later expunging from Thread[RMI TCP Connection(idle),5,RMI Runtime]
ClassLoaderLeakPreventor: Since Java 1.6+ is used, we can call public static final void java.util.ResourceBundle.clearCache(java.lang.ClassLoader)
ClassLoaderLeakPreventor: Releasing web app classloader from Apache Commons Logging

Notice that it is using System.out to log because Logging libraries are common causes of leaked ClassLoaders.

JVM settings

I picked this up from Michael Barnes. You will need to specify the following to make the garbage collector work correctly.

-XX:+UseG1GC -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
  • -XX:+UseG1GC – tells the JVM to use the Garbage First Garbage Collector. This is a new GC for Java 8.
  • -XX:+CMSClassUnloadingEnabled – Tells the GC that class unloading is enabled.
  • -XX:+CMSPermGenSweepingEnabled – Tells the GC that it should enable permanent generation sweeping. Note, this the JVM will give you a message stating that this is unnecessary. Ignore the message, because it will not work without it.

Note that two of the settings are for the Concurrent Mark and Sweep garbage collector. It isn’t documented, but these flags do indeed work.

December 3rd, 2015

Posted In: Java, java ninja, Javaninja

Tags: , , , , , , , , ,

Leave a Comment

LinkedIn Auto Publish Powered By : XYZScripts.com