Monday, November 26, 2012

Tomcat Java Options

On a Unix based system the easiest way to set custom Java options for Tomcat is by adding a file in the <CATALINA_HOME>/bin directory named setenv.sh.  The catalina.sh script checks for the existence of this file and executes it if it exists. Inside this file you would add something similar to the following:

export JAVA_OPTS="-server -Xms2048 -Xmx4096"


Monday, November 12, 2012

AspectJ with Maven and Eclipse Juno

This post will discuss how to use AspectJ with an already existing Maven project in Eclipse.  
First you need to start by downloading AJDT (AspectJ Development Tools) for Eclipse.  

Install AJDT As of this writing, the latest AJDT plugin can be found at:
http://download.eclipse.org/tools/ajdt/42/update.

Convert to AspectJ Project
After downloading and installing the plugin you will need to convert your project to an AspectJ project.  To do so, right click your project in the project explorer and under "Configure" select "Convert to AspectJ Project".  This doesn't stop it from being a Maven project, it simply adds AspectJ support to your project.  

Note: You can remove AspectJ support from your project by right clicking it in the project explorer, selecting "AspectJ Tools" and selecting "Remove AspectJ Capability".

Configure Where Aspects Are Stored
Aspects are by convention in src/main/aspect, but you can configure the plugin to look for aspects by specifying the paths within a .ajproperties file or via your project properties in the "AspectJ Build" pane under "Aspect Path".

Creating a Property File
By convention the property file should be located at your project root, but you can locate it wherever you want if you tell the plugin where to look for it.  Within your pom.xml an entry needs to be added to tell the plugin where to look for it.  Inside the configuration section of the aspectj-maven-plugin add an entry like the following:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifcatId>aspectj-maven-plugin</artifactId>
  <configuration>
    <options>
        ...
      <ajdtBuilderDefFile>src/main/resources</ajdtBuilderDefFile>
    </options>
  </configuration>
  ...
</plugin>

Weaving into 3rd Party Jars
If you are going to be weaving an aspect into a 3rd party class located in a jar file, you will need to add that jar file to your InPath.  Go to your project properties and go to the "AspectJ Build" pane.  There is an InPath tab which allows you to add any jar files you want your aspects woven with.

Configure pom.xml with AspectJ Configuration for Portability
The above is fine if you are the only one developing aspects for the project, however all of the configuration is within the plugin within the IDE so every person wanting to develop aspects for the project will have to configure it.  While developers should still install the AJDT plugin, they won't have to configure the IDE if you put the configuration within the .ajproperties file and pom.xml.  

Add AspectJ Dependency to pom.xml
Within the dependencies section of the pom.xml, add the following snippet:

<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.6.11</version>
</dependency>

Add AspectJ Maven Plugin Build to pom.xml
Within the build section of your pom.xml add the following snippet:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>aspectj-maven-plugin</artifactId>
  <version>1.4</version>
  <configuration>
    <weaveDependencies>
      <weaveDependency>
        <groupId>groupId of jar</groupId>
       <artifactId>name of jar/artifact id</artifactId>
      </weaveDependency>
    </weaveDependencies>
    <ajdtBuildDefFile>build.ajproperties</ajdtBuildDefFile>
  </configuration>
  <executions>
    <execution>
      <phase>process-source</phase>
      <goals>
        <goal>compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>  

The weave dependency specifies the resources that should be woven with your aspects.  The ajdtBuildDefFile property tells the plugin where to look for the property file containing the directories to include with aspect sources and which ones to exclude.

This was mainly written from memory so if you have any issues or find any missing pieces please let me know.

Load Testing with JMeter Plugins

JMeter has come a long way since I first used it about 10 years ago.  At that point I mainly used it to test JMS messages.  Now with the ability to record interactions with web pages and the plethora of samplers, timers, processors, etc it can perform some decent load testing of web applications with the help of some plugins.

The Google Code project JMeter Plugins adds a couple thread groups to allow creation of threads at various points during the test.  It can be found at http://code.google.com/p/jmeter-plugins/.With the basic thread groups in JMeter this was not possible or at least not easy.  Other handy features such as a parameterized controller allow you to create modules and re-use them by passing in different parameters to modify their input and behavior.

There are some limitations I've found which are possible to work around, but can be a little frustrating.  For example, the Ultimate Thread Group shows a nice graph of the number of threads and the durations after you plugin the parameters into the thread group setup.  However, if you intend to dynamically fill those values with user defined variables, then you are out of luck and there won't be a graph displayed to show you what you have just setup.  It will still work however and you can just create another thread group and plugin your actual numbers to see the graph in order to verify your assumptions, but obviously it's not as nice as if it were able to resolve the values and show the graph in the first place.  This may not be a limitation of the plugin itself, but rather a trade-off you'll have to make for re-usability sake.  The Stepping Thread Group doesn't appear to support user defined variables in the setup of the thread group.  So with that one you'll get your pretty graph, but you won't have much flexibility when it comes to being able to swap user defined variables for different tests in and out.

There are also various listeners to be able to view response over time, throughput vs threads, etc.  They give you the type of information you would be looking for when load testing.

If you want to be able to simulate a stepped stress test or load test the JMeter Plugins have very useful features to get the test up and running.

Tuesday, February 14, 2012

Mobile Device Detection Without JavaScript

With the explosion of mobile devices in the form of phones, tablets, readers, etc there has been an increasing need to be able to detect if a user is on a mobile device and to format web content appropriately for them.  There are several methods for detection such as using JavaScript or CSS.  The following article does a good job summarizing the various techniques.

http://webdesign.about.com/od/mobile/a/detect-mobile-devices.htm

The one that seemed the most flexible and future proof is a project called wurfl.  Essentially what it is is a user community maintained list of devices and their capabilities that is continuously updated.  The list is in the form of an xml file that is read by the underlying platform at runtime.  The only downside to this file is that it must be downloaded on a regular basis to maintain a listing of the current devices.  However, this is much preferable to having to write out a long list of things in JavaScript in order to do the detection.

The wurfl project is at http://wurfl.sourceforge.net/

It's pretty simple to use as well, for example to detect if a device is a mobile device or not from a JSP you would execute the following code:

    WURFLHolder wurflHolder = (WURFLHolder) getServletConfig().getServletContext()
            .getAttribute("net.sourceforge.wurfl.core.WURFLHolder");

    WURFLManager wurfl = wurflHolder.getWURFLManager();

    Device device = wurfl.getDeviceForRequest(request);

    Boolean result = new Boolean(device.getCapability("is_wireless_device"));

    if ( result ) {
        System.out.println("This is a mobile device!");
    }
    else {
        System.out.println("This is not a mobile device!");
    }