Tuesday, November 29, 2016

JVM crash due to Loop Unswitching

During performance testing execution on my application stack I came across following fault multiple times. My application stack uses Apache Tomcat 7 and JDK 1.7.0_55.

After investigation found that this is a bug in JDK JIT compiler which is fixed in later version started from update 60.

I had to get the release out and could not afford to upgrade the JDK version so used "-XX:-LoopUnswitching" switch to disable the loop unswitching.

# A fatal error has been detected by the Java Runtime Environment:
#  SIGSEGV (0xb) at pc=0x00002aaab0363f9e, pid=28321, tid=1102854464
# JRE version: 7.0_25-b15
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.25-b01 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# J  org.apache.http.impl.cookie.BestMatchSpec.formatCookies(Ljava/util/List;)Ljava/util/List;
# An error report file with more information is saved as:
# /tmp/hs_err_pid28321.log
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp

Friday, July 22, 2016

ERROR 1215 (HY000) at line 132: Cannot add foreign key constraint

If the data type of table column does not match to foreign key column then during schema creation MySQL throw error ERROR 1215 (HY000) at line 132: Cannot add foreign key constraint

Common mistake is that the foreign key column type is UNSIGNED integer but the column in other table is default integer.

Sunday, February 7, 2016

Gatling simple simulation example

This a simple Gatling simulation example. The POST request is already explained in my earlier blog Gatling post request with JSON body
The example will run the scenario using 5 users for 10 minutes duration with no pauses.
import net.liftweb.json.DefaultFormats
import net.liftweb.json.Serialization._
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.core.scenario.Simulation

class MySimulation extends Simulation {
  case class Person(name: String)

  val createPerson = http("Create person")
    .body(StringBody(session => write(Person("Jack"))(DefaultFormats))).asJSON

  val httpProtocol = http

  val myScenario = scenario("My scenario").during(10) {


Gatling post request with JSON body

To make a POST request in Gatling with JSON request body use the following code -
import net.liftweb.json.DefaultFormats
import net.liftweb.json.Serialization._

object PersonScript {
  case class Person(name: String)

  val createPerson = http("Create person")
    .body(StringBody(session => write(Person("Jack"))(DefaultFormats))).asJSON

The Person case class represents the JSON body structure you want to post.
The StringBody code line converts the case object into JSON representation for post.
Ensure to have following dependency in your classpath.

Gatling read json response and store as list in session

Consider a REST end point /persons which returns JSON response of array of Person object. The Person object having property named id. You want to store all the returned id in personIds list in session to use it further. The REST response is like this -
    "id": 1,
    "name": "Jack",
    "id": 2,
    "name": "Jill"
  val getAllPersons= http("Get all persons")
    .check(status.is(200), jsonPath("$..id").findAll.optional.saveAs("personIds"))

The above code will extract id values and store as list in personIds.
If REST response returns empty list then the above code will fail with error -
jsonPath($..id).findAll.exists, found nothing

Using optional in the chain helps avert the error. Only if the findAll returns any thing the saveAs will execute and will work without failure.

Spring reloadable message source

Spring provides you to externalize your messages so that it can be changed without application restart. Add following snippet to your spring configuration.
    <bean id="messageSource"
        <property name="basenames">
        <property name="cacheSeconds" value="1" />

The messages.file is pointing to property loaded by Spring PropertyConfigurer. For development purposes you can keep the messages file bundled with your project in classpath but for real deployment it will be outside.
The value should be like classpath:messages where the messages.properties file is kept in src/main/resources. The value can be messages.file=file:D:/config/messages if its kept out at this location.
The Spring messages are by default internalized so if you have done that setup it can pickup files like messages_en_GB.properties as per the locale.

Spring externalize application configuration

To configure your application is different environment using different setup use the following in Spring framework -
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
        <property name="ignoreResourceNotFound" value="true" />
        <property name="searchSystemEnvironment" value="true" />
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
By default it will read the default.properties available in your application classpath. Typically it is available at src/main/resources/default.proerties.

Setup environment variable APPLICATION_CONFIG_HOME which points to directory where customer application.properties is available. If the file is available then it will override those properties which you have specified in that file.

For local development user need not required to define this as mostly developers will use the default.properties.

This setup provies an option to override if required in a particular environment e.g. QA, performance, staging, production, etc.

Spring data JPA Pessimistic lock

If you want to lock a database record to execute certain business logic and do not want any other thread to update the same then do the following -
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

import javax.persistence.LockModeType;

public interface PersonRepository extends CrudRepository {
    @Query("select p from Person p where p.id = :id")
    Person findOneAndLock(@Param("id") int id);
In this example Person is an entity and I want to lock a Person record based on id. The service layer method must be in transaction to use this method.

Simple Gatling setup with Maven

Just add the following maven pom snippet to your project pom.xml.

Create maven style project structure of src/test/scala. As per the example below your default simulation class is com.company.project.MySimulation. If you want to create different name/package pass -Dsimulation= to execute that simulation.

All of the properties mentioned in the pom can be overridden via command line using -D option.

Execute mvn test to run your gatling performance simulation.