Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

The SpringFramework has a RestTemplate object that can be used to HTTP-based network calls. It doesn’t timeout by default, but there is functionality that can be configured. A RequestFactory must be created, then it needs to be wired into the RestTemplate.

The readTimeout and the connectionTimeout are both expressed in milliseconds.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd>
 
    <bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"
          p:readTimeout="250"
          p:connectTimeout="250"/>
 
    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"
          c:requestFactory-ref="requestFactory"/>
</beans>

Once you have the RequestFactory configured, then the RestTemplate will begin to throw SocketTimeoutException and ConnectTimeoutException, depending on the problem. This is normally handled by catching RestClientException. This RuntimeException wraps all exceptions that are throws by the RestTemplate.

String response = null;
try {
    response = restTemplate.getForObject(url, String.class);
} catch (RestClientException e) {
    createOrderResponse.setStatus("failure");
    logger.error("Unable to get the PayNearMe barcode URL", e);
    //FIXME do something with the exception
    //throw e;
}

Catching the RestClientException is usually enough, because you only want to know that there is a problem. However, if you need to know the specific problem, you can test the RootCause for the specific type of exception.

String response = null;
try {
    response = restTemplate.getForObject(url, String.class);
} catch (RestClientException e) {
    createOrderResponse.setStatus("failure");
    if (e.getRootCause() instanceof SocketTimeoutException) {
        logger.error("SocketTimeoutException", e);
    } else if (e.getRootCause() instanceof ConnectTimeoutException) {
        logger.error("ConnectTimeoutException", e);
    } else {
        logger.error("Some other exception", e);
    }
    //FIXME do something with the exception
    //throw e;
}

September 13th, 2016

Posted In: Java, java ninja, Javaninja, Spring

Leave a Comment

I don’t do a lot with Hibernate directly, but sometimes I do. I had seen Hibernate inheritance before, but I never had to make one. The pattern that was in place was there was a table that had common information. There was another table that had information that was implementation-specific and there were multiple implementations. My job was to add another implementation. To accomplish the writing of the data, they had a Hibernate entity for the common table. This entity was extended by an implementation-specific entity. Then they would populate the entity and save it. Effectively writing to two tables with one logical write.

The InheritanceType is JOINED. This sets it up to be joined on by other tables (e.g. extended). The base entity was defined as follows:

@Entity
@Table(name = "FundsAudit")
@Inheritance(strategy = InheritanceType.JOINED)
public class FundsAudit {

    @Id
    @Column(name = "FundTypeKey")
    private String fundTypeKey;

    //...

}

I had to add an @InheritanceType as SINGLE_TABLE. Which basically says a table per entity. I also specified @PrimaryKeyJoinColumn. The referencedColumnName is the name of the column in the inherited table. The name is the name of the column in the entity that is extending the base table. Note that you don’t see that column listed in the entity that is being extended. That table does in fact exist. This is what I came up with to extend the base entity.

@Entity
@Table(name = "paynearme_audit")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@PrimaryKeyJoinColumn(referencedColumnName = "FundTypeKey", name = "FundTypeKey")
public class PayNearMeAudit extends FundsAudit {

    //@Id  NOTE:  You don't use ID in an entity that is inherited

    @Column(name = "PayNearMe_Order_ID")
    private long payNearMeOrderIdentifier;

    //...

}

Once I have my entities defined, it is very simple to use the object. I use the entity that I created, that extends the base entity. In my code, that is all you see referenced. I have fields from both entities/tables available to me.

PayNearMeAudit payNearMeAudit = new PayNearMeAudit();
payNearMeAudit.setAffiliateId(affiliateId);
payNearMeAudit.setHandler(String.valueOf(accountNumber));
payNearMeAudit.setPayNearMeOrderIdentifier(Long.parseLong(payNearMeOrderIdentifier));
payNearMeAudit.setTransactionDateTime(new Date());
payNearMeAudit.setTransactionType(TransactionType.Deposit.toString());
payNearMeAudit.setStatus("initiated");
payNearMeAudit.setAmount(amount);
payNearMeAudit.setFundTypeKey(new IdGeneratorImpl().generateOrderId(FundingCache.get(Constants.SITE_ID)));
payNearMeAudit.setFundType(FundType.PayNearMe.toString());
payNearMeAudit.setResponse("{\"payNearMeOrderIdentifier\":\"" + payNearMeOrderIdentifier + "\"}");
payNearMeAuditDao.insert(payNearMeAudit);
payNearMeAudit = payNearMeAuditDao.findByPayNearMeOrderIdentifier(Long.parseLong(payNearMeOrderIdentifier));

I need to ensure that I specify the value of the join column, fundTypeKey. Other than that, it just works. If you are reading the code, you would never have any idea that you were doing anything out of the ordinary.

August 30th, 2016

Posted In: hibernate

Leave a Comment

I was working on Java some code. It had two different objects that extended a common base object. There was a method that was called to load the common values. The receiving methods would then cast the returned object to the type that it was given. Here was the original code:

private ConvergeBaseRequest setProperties(ConvergeBaseRequest request) {
    // do some stuff
    request.setSslMerchantId(merchantId);
    request.setSsluserId(userId);
    request.setSslPin(pin);
    return request;
}

It was called by:

request = (ConvergeCCSaleRequest) setProperties(request);

After a little tweaking, I came up with the following method:

private <T extends ConvergeBaseRequest> T setProperties(T request) {
    // do some stuff
    request.setSslMerchantId(merchantId);
    request.setSsluserId(userId);
    request.setSslPin(pin);
    return request;
}

This made it simpler to call also,

request = setProperties(request);

With just a little bit of smarts, we were able to use Java Generics to make our calling code a little bit simpler.

July 19th, 2016

Posted In: Java, java ninja, Javaninja

Leave a Comment

I like to use SpringMVC for my JSON controllers. I do not prefer to return HTTP status codes other than 200, but sometimes you don’t have a choice. I was working on a project where the service would return the requested resource when it is available. If the resource is not found, then it is supposed to return an HTTP status of 404 with a messages. I thought this would be included right out of the box, but it wasn’t.

What Spring MVC offers and why it didn’t work

With Spring MVC, you have the ability to define an exception and have that exception return a specified HTTP status code when it reaches the controllers. Here is what an exception class would look like:

package com.twinspires.brisdataapi.bdsserver.exceptions;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * @author norris.shelton
 */
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class NotFoundException  extends RuntimeException {
    /**
     * Constructs a new runtime exception with the specified detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()}
     *                method.
     */
    public NotFoundException(String message) {
        super(message);
    }
}

This does provide a way to specify a message, but it doesn’t get displayed when a message is returned by the controllers. Ugh.

This would provide a good start, but I would need an exception handler to get the message. Unfortunately, all of the examples of the exception handlers show a method per exception.

Doing the least to make it work

This details the changes that I needed to make to allow the service to function correctly. I wanted to create as few classes as possible.

Define an exception

I created an exception that extends RuntimeException. I didn’t add a @ResponseStatus because I didn’t want to have to make an exception for each status code. I created a constructor that takes an HTTP status code and a message. This allows me to have one exception that I can reuse in all of my controllers and always return the correct status and message.

package com.twinspires.brisdataapi.bdsserver.exceptions;

import org.springframework.http.HttpStatus;

/**
 * @author norris.shelton
 */
@SuppressWarnings("ClassWithoutNoArgConstructor")
public class BdsServiceException extends RuntimeException {

    private HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

    /**
     * Constructs a new runtime exception with the specified detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()}
     *                method.
     */
    public BdsServiceException(HttpStatus httpStatus, String message) {
        super(message);
        this.httpStatus = httpStatus;
    }
}

Define SpringMVC exception handler

Now that I have an exception that has all of the information that I want returned to the caller of my service, I need to define an exception handler. It is the same type of exception handler that you normally see, except it returns a ResponseEntity. With the ResponseEntity, I can return the retrieve the correct status code and message from the exception and return them to the caller.

package com.twinspires.brisdataapi.bdsserver.spring;

import com.twinspires.brisdataapi.bdsserver.exceptions.BdsServiceException;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class ExceptionHandlerAdvice { 
 
    @ExceptionHandler(BdsServiceException.class)
    public ResponseEntity handleException(BdsServiceException e) {
        // log exception 
        return ResponseEntity.status(e.getHttpStatus()).body(e.getMessage());
    }         
} 

Putting it to use

All that is left is throwing the exception. I threw the exception with the desired HTTP status code and the message.

            throw new ResourceException(HttpStatus.NOT_FOUND, "We were unable to find the specified resource.");

June 22nd, 2016

Posted In: Java, java ninja, Javaninja, Spring, Spring MVC

Leave a Comment

We were using FasterXML on the same object to generate JSON and XML. Unfortunately, the object itself didn’t define the desired markup. It used JAXB annotations to add a wrapper around a set of data.

XML and JSON output based upon class definition

The class had the following property defined:

public List<TestRacingEventResponse> getRacingEvents() { return _racingEvents; }
public void setRacingEvents(List<TestRacingEventResponse> racingEvents) { this._racingEvents = racingEvents; }

This would generate XML like:

<racingEvents>
    <....>
</racingEvents>
<racingEvents>
    <....>
</racingEvents>
<racingEvents>
    <....>
</racingEvents>

The JSON would be outputted like this:

{racingEvents
{…}
}
{racingEvents
{…}
}
{racingEvents
{…}
}

JAXB to create a wrapper and redefine the element

This isn’t what was wanted. The desired output was a racingEvents container around a list of racingEvent containers. This is quite easy in XML via JAXB. The declaration with the required JAXB is as follows:

@XmlElementWrapper(name="racingEvents")
@XmlElement(name="racingEvent")
public List<TestRacingEventResponse> getRacingEvents() { return _racingEvents; }
public void setRacingEvents(List<TestRacingEventResponse> racingEvents) { this._racingEvents = racingEvents; }

This would generate XML like:

<racingEvents>
    <racingEvent>
        <....>
    </racingEvent
    <racingEvent>
        <....>
    </racingEvent
    <racingEvent>
        <....>
    </racingEvent
</racingEvents>

This works great for XML, but JSON doesn’t honor JAXB annotations. This leaves us with two alternatives. Create a class structure that mimics the structures you wanted. That would be creating a RacingEvents property in our enclosing class that is a List, then create a RacingEvent object that has the required fields.

Configure FasterXML (Jackson 2) to honor JAXB Wrapper annotation

Another way to do this is to instruct the JSON marshaller to honor the JAXB annotations. We are using Jackson 2 (FasterXML). In our particular case, we were using CXF for the front-end services. The original XML configuration is as follows:

<jaxrs:server id="hptsWebService" address="/">
    <jaxrs:serviceBeans>
        <bean id="accountServices" class="com.twinspires.hpts.servicedefinitions.AccountServices"/>
        <bean id="racingContentServices" class="com.twinspires.hpts.servicedefinitions.RacingContentServices"/>
        <bean id="systemInfoServices" class="com.twinspires.hpts.servicedefinitions.SystemInfoServices"/>
        <bean id="testerServices" class="com.twinspires.hpts.servicedefinitions.TesterServices"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/>
    </jaxrs:providers>
</jaxrs:server>

I needed to be able to configure the ObjectMapper. Unfortunately, I couldn’t get to the ObjectMapper in the code because the JacksonJaxbJsonProvider only exposed a MAPPER. That seems like a bug to me. To get around this, I declared the JacksonJaxbJsonProvider separately.

<bean id="jacksonJaxbJsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/>

<jaxrs:server id="hptsWebService" address="/">
    <jaxrs:serviceBeans>
        <bean id="accountServices" class="com.twinspires.hpts.servicedefinitions.AccountServices"/>
        <bean id="racingContentServices" class="com.twinspires.hpts.servicedefinitions.RacingContentServices"/>
        <bean id="systemInfoServices" class="com.twinspires.hpts.servicedefinitions.SystemInfoServices"/>
        <bean id="testerServices" class="com.twinspires.hpts.servicedefinitions.TesterServices"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <ref bean="jacksonJaxbJsonProvider"/>
    </jaxrs:providers>
</jaxrs:server>

Now that the object is separate, I had to find a place where I could manipulate it. I found an object that was related to the functionality that I needed and added a constructor that took the JacksonJaxbJsonProvider as input. Once I had that object, I could configure to my heart’s content.

My modifications involved creating a new OjbectMapper. I preferred to get the ObjectMapper that was being used, but there was no getter. Once I have the ObjectMapper, I set a property that indicates that I want use the XmlElementWrapper as a wrapper for my output.

    @Autowired
    public HttpUtil(JacksonJaxbJsonProvider jacksonJaxbJsonProvider) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME);
        jacksonJaxbJsonProvider.setMapper(objectMapper);
    }

Now that we have told the JSON marshaller to honor the JAXB wrapper annotation, output should be:

{racingEvents
    {races
        {...}
    }
    {races
        {...}
    }
    {races
        {...}
    }
}

Conclusion

To have a FasterXML honor JAXB annotations when it outputs JSON, you have to instantiate the JacksonJaxbJsonProvider separately so it can be injected. Once it is injected in code, you can create and configure an ObjectMapper.

June 10th, 2016

Posted In: FasterXML, Jackson 2, Java, java ninja, Javaninja, JAXB, json

One Comment

Accessing properties via Spring is very easy. To read a properties file is very easy. This reads the given properties file from the file system and places the values in a map named rabbitConfiguration. It takes advantage of SpEl to get a system property and use that to resolve the file name.

<util:properties id="rabbitConfiguration" location="file:#{systemProperties.APP_CONFIG}/funding.properties"/>

My problems started when I tried to use the values from the properties file that contained periods. I tried to use them like:

    <bean id="rabbitConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory"
          c:hostname="#{rabbitConfiguration.vipre.host}"
          c:port="#{rabbitConfiguration.vipre.port}"
          p:username="#{rabbitConfiguration.vipre.user}"
          p:password="#{rabbitConfiguration.vipre.password}"/>

Spring did not like it. It thought that vipre was my property and host was something to be accessed off of it like an object. This is the exception that was thrown.

Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 20): Property or field 'vipre' cannot be found on object of type 'java.util.Properties' - maybe not public?
	at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:164)
	at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java:1365)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.doEvaluate(BeanDefinitionValueResolver.java:255)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.evaluate(BeanDefinitionValueResolver.java:228)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:204)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:648)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1137)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1040)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
	... 109 common frames omitted
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 20): Property or field 'vipre' cannot be found on object of type 'java.util.Properties' - maybe not public?
	at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:224)
	at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94)
	at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:81)
	at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:57)
	at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:87)
	at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120)
	at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242)
	at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:161)
	... 124 common frames omitted

I searched and searched around the internet trying to find a way to work around. I tried single-quotes, back-slashes, double-quotes, double-quotes and single-quotes together. Nothing seemed to work, then it hit me. To get around this, I approached the properties access via the array/bracket syntax (#{rabbitConfiguration[‘vipre.port’]}

    <bean id="rabbitConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory"
          c:hostname="#{rabbitConfiguration['vipre.host']}"
          c:port="#{rabbitConfiguration['vipre.port']}"
          p:username="#{rabbitConfiguration['vipre.user']}"
          p:password="#{rabbitConfiguration['vipre.password']}"/>

May 31st, 2016

Posted In: Java, java ninja, Javaninja, SpEl, Spring

Leave a Comment

Spring provides the SimpleNamingContextBuilder to handle cases where the code that is tested needs a JNDI environment entry.

Steps to using a Spring SimpleNamingContextBuilder

Using the Spring SimpleNamingContextBuilder is fairly easy. There are basically three steps:

  1. Instantiate the variable
  2. Bind objects to their JNDI keys in the context builder (repeat as necessary)
  3. Activate the context builder

Full Example Utility

In my case, I only had to bind one thing, the full path to a file.

Here is the utility class that I built to hold the code.

package com.twinspires.cam;

import org.springframework.mock.jndi.SimpleNamingContextBuilder;

import javax.naming.NamingException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.junit.Assert.fail;

/**
 * @author norris.shelton
 */
public class JunitTestUtility {

    /**
     * Performs environmental setup for Cam tests.
     * @throws NamingException if unable to activate the builder
     * @throws URISyntaxException if unable to find the properties file by a classloader
     */
    public static void setup() throws NamingException, URISyntaxException {
            String camPropertiesFile = "cam-test.properties";
        URL url = JunitTestUtility.class.getClassLoader().getResource(camPropertiesFile);
        if (url != null) {
            Path path = Paths.get(url.toURI());
            if (path != null) {
                SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
                builder.bind("cam.config.path", path.toString());
                builder.activate();
            }
        } else {
            fail("Unable to find cam-test.properties in src/test/resources");
        }
    }
}

How to reuse in a Junit test class

Once that is done, it is quite easy to reuse it. In my case, all of the test classes for a project needed that.

    @BeforeClass
    public static void setup() throws Exception {
        JunitTestUtility.setup();
    }

May 24th, 2016

Posted In: Java, java ninja, Javaninja, JUnit, Spring, TDD

Leave a Comment

Get JMeter

Download the software from Apache from http://jmeter.apache.org/download_jmeter.cgi. I use IntelliJ. It says to define a JMETER_HOME environment variable. Once you have that, you should be able to create JMeter file times (*.jmx). If you right-click on a *.jmx file, IntelliJ will give you the option to run the file. Running the file will open the JMeter application with the specified file.

Test Plan

The test plan is the first item in the left-hand panel. It looks like a Erlenmeyer flask. This is where you will put the name of your test.

You can create User Defined Variables that can be used in other places in the test. An example a user defined variable with the name host and a value of localhost. It can be used by ${host}. Then later, the value can be changed to test to another server.

Thread Group

You can add a Thread Group by right-clicking on the Test Plan and selecting Threads (Users), then Thread Group. It looks like a spool of thread. The thread group is used to control the load. What should happen if there is a sampler error? Continue and Stop Thread are common options.

There is a Thread Properties box that has most of the options here. You can control how many threads (users) you have, how long it takes to ramp up a thread. One second is the default. You can also specify how many iterations (Loop Count) you should perform.

There is also a Scheduler checkbox. If you select that, then there will be a Scheduler Configuration that will become visible. That is good when you want the test to run for a specified amount of time, instead of iterations. You don’t have to specify the Start Time or the End Time. All you need to specify is the Duration (seconds>. If you want a test to run 5 minutes, specify 300 seconds.

HTTP Request

You can add an HTTP Request by right-clicking on the Thread Group, selecting Add, Sampler, then selecting HTTP Request. It looks like a dropper. The http request is where you can specify and control the http request. Some of the things you can specify:

  • server Name or IP. I would use a User Defined Variable here (e.g. ${host}).
  • port
  • connection and response timeouts
  • protocol (defaults to http)
  • HTTP method (defaults to GET)
  • path
  • URL parameters
  • post body data

Once you have something that can generate results, there are several different ways to be presented the data.

View Results Tree

You can add a View Results Graph by right clicking the HTTP Request, then selecting Add, then Listener, then View Results Tree. The icon looks like a dial meter. The View Results Tree is very helpful in debugging your test. It shows each request and each response. There is also the ability to format the response by type, for example JSON.

One caveat with this is that if you have a very long running test or a lot of data, your JMeter will run out of memory. To counter this, you can have it write the data to a file. I usually just disable the View Results Tree by right-clicking on it and clicking disable.

View Results in Table

You can add a View Results in Table by right clicking the HTTP Request, then selecting Add, then Listener, then View Results in Table. The icon looks like a dial meter. The View Results in Table shows the results in tabular format. It has timing information.

Sample #  Start Time	Thread Name       Label         Sample Time(ms)  Status   Bytes  Latency  Connect Time(ms)
19        08:56:26.194  Thread Group 1-1  HTTP Request  9                Success  383    8        2

This is usually the panel I have open when I am running a test. The panel bottom line shows the average and the standard deviation. You can write the results to a file.

Response Time Graph

You can add a Response Time Graph by right clicking the HTTP Request, then selecting Add, then Listener, then Response Time Graph. The icon looks like a dial meter. The Response Time Graph shows the results in in a graphical format. Typically time horizontally and milliseconds vertically. This can also be written to a file.

Summary Report

You can add a Summary Report by right clicking the HTTP Request, then selecting Add, then Listener, then Summary Report. The icon looks like a dial meter. The Summary Report outputs timing information for each JMeter Sampler (e.g. HttpRequest).

Label         # Samples  Average  Min  Max  Std. Dev.          Error %  Throughput         KB/sec              Avg. Bytes
HTTP Request  45619      22       17   115  6.598780184509035  0.0      387.7254415339373  211.72920469177618  559.1861724281549
TOTAL         45619      22       17   115  6.598780184509035  0.0      387.7254415339373  211.72920469177618  559.1861724281549

Generate Summary Results

You can add a Generate Summary Results by right clicking the HTTP Request, then selecting Add, then Listener, then Generate Summary Results. The icon looks like a dial meter. The Generate Summary Results outputs a summarized timing data to the console. The output is below. Notice that every other line is a summary to that point and the others are deltas.

Generate Summary Results +   3265 in     9s =  366.9/s Avg:    22 Min:    17 Max:   110 Err:     0 (0.00%) Active: 10 Started: 10 Finished: 0
Generate Summary Results +  13024 in    30s =  434.1/s Avg:    22 Min:    17 Max:   110 Err:     0 (0.00%) Active: 10 Started: 10 Finished: 0
Generate Summary Results =  16289 in    39s =  418.7/s Avg:    22 Min:    17 Max:   110 Err:     0 (0.00%)
Generate Summary Results +  11524 in    30s =  384.2/s Avg:    21 Min:    17 Max:   112 Err:     0 (0.00%) Active: 10 Started: 10 Finished: 0
Generate Summary Results =  27813 in    69s =  403.7/s Avg:    22 Min:    17 Max:   112 Err:     0 (0.00%)
Generate Summary Results +  12283 in    30s =  409.4/s Avg:    22 Min:    17 Max:   115 Err:     0 (0.00%) Active: 10 Started: 10 Finished: 0
Generate Summary Results =  40096 in    99s =  405.4/s Avg:    22 Min:    17 Max:   115 Err:     0 (0.00%)
Generate Summary Results +    411 in   1.3s =  324.6/s Avg:    20 Min:    17 Max:    26 Err:     0 (0.00%) Active: 0 Started: 10 Finished: 10
Generate Summary Results =  40507 in 100.2s =  404.4/s Avg:    22 Min:    17 Max:   115 Err:     0 (0.00%)

CSV Data Set Config

Needing to run a data-driven test is very common. How do you get JMeter to use data in it’s tests? Use a CSV, of course. You can add a CSV Data Set Config by right clicking the Thread Group, then selecting Add, then Config Element, then CSV Data Set Config. The icon looks like test tubes in a test tube rack. The CSV Data Set Config has the following fields:

  • Filename – the name of the file containing the data
  • File Encoding – file encoding (optional)
  • Variable names (comma-delimited) – the names of the data fields, in order. These names will be available like User Defined Variables (e.g. id -> ${id}, according to the Sharing Mode described below.
  • Delimeter – “,” or “\t” for tab, etc. or use specified value
  • Allow quoted data? – true or false or use specified value
  • Recycle on EOF ? – true or false or use specified value
  • Stop thread on EOF ? – true or false or use specified value
  • Sharing mode – All threads, current thread group, current thread or use specified value

Once you have this configured, you can use the exposed CSV data just as a User Defined Variable that changes per entry in HTTP Requests, etc. Then you can substitute the value in the Path as a URL parameter or path parameter. You can also use them in the body of the post, etc.

HTTP Header Manager

HTTP Header Manager can be used to inject headers to indicate the Content-Type, Accept, etc. You can add a CSV HTTP Header Manager by right clicking the HTTP Request, then selecting Add, then Config Element, then HTTP Header Manager.

HTTP Authorization Manager

HTTP Authorization Manager can be used to inject authorization header information into a request. You can add a HTTP Authorization Manager by right clicking the HTTP Request, then selecting Add, then Config Element, then HTTP Authorization Manager.
The following fields are available:

  • Base URL – URLs to send the authorization header
  • Username – the username to authorize
  • Password – the unencrypted password value
  • Domain – The domain to use for NTLM
  • Realm – The realm to use for NTLM
  • Mechanism – Type of authorization to perform. This depends on the Sampler Mechanism that is specified on HTTP Request in the Implementation field.

Most of the marshalling I have to do it done by Spring. However, I sometimes have to do this manually. Let’s see how easy it is with Jackson 2 (FasterXML).

Maven dependency

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.3</version>
</dependency>

Import the ObjectMapper

The ObjectMapper is the object that you will instantiate and use for all conversions.

import com.fasterxml.jackson.databind.ObjectMapper;

Object to String

Given an object, it is pretty easy to use an ObjectMapper.

ObjectMapper objectMapper = new ObjectMapper();
String myString = objectMapper.writeValueAsString(myObject);

String to Object

If you have a JSON string and need to convert that to an object, you also use the ObjectMapper.

ObjectMapper objectMapper = new ObjectMapper();
MyObject myObject = objectMapper.readValue(myJsonString, MyObject.class);

May 12th, 2016

Posted In: FasterXML, Java, java ninja, Javaninja, json

Leave a Comment

Creating a thread pool within a web application is usually frowned upon. Why is that?

  • If you create your thread pool within the web application context, your pool will be competing for threads with your web application.
  • Another problem with creating your thread pool within the web application context is that you don’t know what assumptions the web container makes about what is available in the thread. It could be storing information related to security, etc on the thread.
  • Another problem with creating threads within the web application context is that those threads will respond to the web application shutdown. This may be counter to what you want to happen. Those threads may need to run to completion, regardless of the desire to shutdown the web application context.

Creating our Spring thread worker

Now that we know what not to do and why, let’s start with the right way to do this. The first thing is that we need to implement a bean to perform our work. There a couple of things that will need to be different from other generic beans.

  • The beans should be scope Prototype. Spring beans default to Singleton scope. That means that there is one bean per Spring container. When you are making worker threads, they should be scoped as prototype. That means that a new bean is created whenever one is requested.
  • The class should implement the Runnable interface. This dictates that a run method must be implemented. This method is called when the thread is started as a separately executing thread.

Here is an example thread worker. It is scoped Prototype and implements Runnable. It doesn’t do much, but waits a random amount of time to simulate asynchronous work. I added a field with a custom value and a little logging so we can see the workings of the threads via the logs.

package com.javaninja.spring.webmvc.threads;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

/**
 * This class performs the work that is needed in the thread pool.
 * @author norris.shelton
 */
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ThreadWorker implements Runnable {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private String uniqueInfo;

    private List<String> data = new LinkedList<>();


    public void setUniqueInfo(String uniqueInfo) {
        this.uniqueInfo = uniqueInfo;
    }

    public List<String> getData() {
        return data;
    }


    /**
     * When an object implementing interface {@code Runnable} is used to create a thread, starting the thread
     * causes the object's {@code run} method to be called in that separately executing thread.
     * <p>
     * The general contract of the method {@code run} is that it may take any action whatsoever.
     * @see Thread#run()
     */
    @Override
    public void run() {
        logger.info("Started runner {}", uniqueInfo);

        try {
            int milliseconds = new Random().nextInt(10000);
            logger.info("{} sleeping for {} ms", uniqueInfo, milliseconds);
            Thread.sleep(milliseconds);
        } catch (InterruptedException e) {
            logger.error("Trouble with thread", e);
        }

        // simulating having results
        for (int i = 0; i < 5; i++) {
            data.add(UUID.randomUUID().toString());
        }

        logger.info("Runner {} finishing data={}", uniqueInfo, data);
    }

    /**
     * Returns a string representation of the object. In general, the {@code toString} method returns a string that
     * "textually represents" this object. The result should be a concise but informative representation that is easy
     * for a person to read. It is recommended that all subclasses override this method.
     * <p>
     * The {@code toString} method for class {@code Object} returns a string consisting of the name of the class of
     * which the object is an instance, the at-sign character `{@code @}', and the unsigned hexadecimal representation
     * of the hash code of the object. In other words, this method returns a string equal to the value of: <blockquote>
     * <pre>
     * getClass().getName() + '@' + Integer.toHexString(hashCode())
     * </pre> </blockquote>
     * @return a string representation of the object.
     */
    @Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this);
    }
}

Defining our Spring thread pool

Spring provides the ThreadPoolTaskExecutor class that takes out most of the difficulty. It provides some customization that proves to be extremely useful. Some of the settings are below:

  • corePoolSize – This is minimum pool size. The default value is 1.
  • maxPoolSize – This is the maximum pool size. the default is Integer.MAX_VALUE.
  • waitForTasksToCompleteOnShutdown – Should the pool wait for tasks to complete when the Spring container is shutdown. The default value is false.
  • awaitTerminationSeconds – How long should the Spring container wait for the pool to finish its tasks when the Spring container is told to shut down.

An example is below:

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"
          p:corePoolSize="5"
          p:maxPoolSize="5"
          p:waitForTasksToCompleteOnShutdown="true"
          p:awaitTerminationSeconds="20"/>

Using a pool with fixed workers

Our first example will have a fixed number of worker threads. This is the simplest way to do it if you know you will always have a specific number of thread workers. The first thing to do to use the pool is get a reference to the TaskExecutor. Then inject the number of workers that we will need. Remember that these workers are all scoped Prototype to ensure that each can work completely independent of each other. I set a unique value into each thread worker and have each one of them sleep a random amount of time to help identify it while it is working. To start a worker we call the execute method on the thread pool with our worker as the method parameter.

package com.javaninja.spring.webmvc.threads;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * This is the code that controls the execution of a fixed number of worker threads.
 * @author norris.shelton
 */
@Service
public class FixedThreadService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    private ThreadWorker worker1;

    @Autowired
    private ThreadWorker worker2;

    @Autowired
    private ThreadWorker worker3;

    @Autowired
    private ThreadWorker worker4;

    @Autowired
    private ThreadWorker worker5;

    public String withFixedThreads() {
        worker1.setUniqueInfo("1");
        taskExecutor.execute(worker1);

        worker2.setUniqueInfo("2");
        taskExecutor.execute(worker2);

        worker3.setUniqueInfo("3");
        taskExecutor.execute(worker3);

        worker4.setUniqueInfo("4");
        taskExecutor.execute(worker4);

        worker5.setUniqueInfo("5");
        taskExecutor.execute(worker5);

        return UUID.randomUUID().toString();
    }
}

Using a pool with dynamic workers

Sometimes we don’t know how many worker threads we will need until runtime. This requires a slightly different solution. We will need access to the Spring context to create as many workers as needed. Remember that the thread worker classes are scoped as Prototype. This means that each time we request a bean via getBean, that we are getting a totally new bean that will execute completely independent of any other thread worker bean. From there, the code is similar and will actually be shorter.

NOTE: to get the Spring context during the execution of the bean, you should implement ApplicationContextAware. This dictates that you have a setApplicationContext method. Once you have the context injected, you can use it however you need. To inject beans on demand, in our case.

package com.javaninja.spring.webmvc.threads;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * This is the code that controls the execution of a dynamic number of worker threads.
 * @author norris.shelton
 */
@Service
public class DynamicThreadService implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    /**
     * Set the ApplicationContext that this object runs in. Normally this call will be used to initialize the object.
     * <p>Invoked after population of normal bean properties but before an init callback such as {@link
     * InitializingBean#afterPropertiesSet()} or a custom init-method. Invoked after {@link
     * ResourceLoaderAware#setResourceLoader}, {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
     * {@link MessageSourceAware}, if applicable.
     * @param applicationContext the ApplicationContext object to be used by this object
     * @throws ApplicationContextException in case of context initialization errors
     * @throws BeansException              if thrown by application context methods
     * @see BeanInitializationException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public String withDynamicThreads(int threads) {

        ThreadWorker threadWorker = null;
        for (int i = 0; i < threads; i++) {
            threadWorker = applicationContext.getBean("threadWorker", ThreadWorker.class);
            threadWorker.setUniqueInfo(String.valueOf(i));
            taskExecutor.execute(threadWorker);
        }

        return UUID.randomUUID().toString();
    }
}

Running a pool with thread workers

The pool will run like normal. One thing to note is that we wanted our pool to continue processing, even if the server is requested to shut down. You can see by the logging that the threads continue to process. Success. The threads operate independent of the web application container and the Spring container.

INFO |Initializing ExecutorService  'taskExecutor' ||org.springframework.scheduling.concurrent.ExecutorConfigurationSupport:165 
INFO |Started runner 4 ||com.javaninja.spring.webmvc.threads.ThreadWorker:48 
INFO |Started runner 1 ||com.javaninja.spring.webmvc.threads.ThreadWorker:48 
INFO |Started runner 2 ||com.javaninja.spring.webmvc.threads.ThreadWorker:48 
INFO |Started runner 5 ||com.javaninja.spring.webmvc.threads.ThreadWorker:48 
INFO |Started runner 3 ||com.javaninja.spring.webmvc.threads.ThreadWorker:48 
INFO |4 sleeping for 8116 ms ||com.javaninja.spring.webmvc.threads.ThreadWorker:52 
INFO |1 sleeping for 586 ms ||com.javaninja.spring.webmvc.threads.ThreadWorker:52 
INFO |2 sleeping for 6754 ms ||com.javaninja.spring.webmvc.threads.ThreadWorker:52 
INFO |5 sleeping for 8060 ms ||com.javaninja.spring.webmvc.threads.ThreadWorker:52 
INFO |3 sleeping for 8841 ms ||com.javaninja.spring.webmvc.threads.ThreadWorker:52 
INFO |Closing org.springframework.context.support.GenericApplicationContext@491cc5c9: startup date [Tue May 10 10:01:27 EDT 2016]; root of context hierarchy ||org.springframework.context.support.AbstractApplicationContext:960 
INFO |Shutting down ExecutorService 'taskExecutor' ||org.springframework.scheduling.concurrent.ExecutorConfigurationSupport:203 
INFO |Runner 1 finishing data=[8aa9a123-5d0f-42d0-8be4-b703705a7a5c, 10de5358-5c7f-4881-9f9d-7706ea6ae8dd, 3f23f9c8-a594-4228-8a91-5eab26fb4d39, 6a52ec9c-82ec-4b88-bfdd-4b413291a8fe, d000aa8c-8c4d-4f6f-9dd5-c63c44431bcd] ||com.javaninja.spring.webmvc.threads.ThreadWorker:63 
INFO |Runner 2 finishing data=[cceed519-1cc9-4ce0-bdf4-02703f624853, 342f024c-c785-47a7-b4b4-aec261341fa7, 56c54700-37ac-41aa-89a2-3d1b4f92b6ed, 2ba81d54-d52b-4b4c-a26a-06996d25c2b9, c7a5e66c-b196-4936-a5aa-5ada8b416b7d] ||com.javaninja.spring.webmvc.threads.ThreadWorker:63 
INFO |Runner 5 finishing data=[159e842e-aaf8-4f86-9e01-1c814043943d, 59fa91bf-cd6a-4ad2-b7bd-8de85d5223f2, 360da0f9-91c8-4682-8d88-23a4f7327b98, a23824c5-f52a-426b-8c16-f5ec223c90cd, 0862d9a1-1635-4d15-8f7f-911877ac7165] ||com.javaninja.spring.webmvc.threads.ThreadWorker:63 
INFO |Runner 4 finishing data=[e26c4269-804c-4a6c-ae08-dc798e6f550c, 709bbf44-f480-4f32-834b-d5c8fc095b81, 807d311d-5a68-48b0-b2a6-cb74d596ee32, e4beeeeb-6628-4261-8a44-dc19a205c71a, a87c24b8-f693-4461-a54d-8a101fbc2a59] ||com.javaninja.spring.webmvc.threads.ThreadWorker:63 
INFO |Runner 3 finishing data=[389b2d85-4a64-4ea8-8b35-39480e027614, 5c85f6d0-a59e-4b7a-95be-e0ab9822e487, efb164c3-dc07-4a73-ae1f-c14c2f05ba08, 33a78ef4-8d67-4566-b20b-c74044012086, e75222f3-bf78-486f-b9e3-9b244f3237e3] ||com.javaninja.spring.webmvc.threads.ThreadWorker:63 

Process finished with exit code 0

Project files

The code for this project is in sheltonn / spring-web-threads

May 10th, 2016

Posted In: Java, java ninja, Javaninja, Spring

Leave a Comment

Next Page »
LinkedIn Auto Publish Powered By : XYZScripts.com