Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts

Monday, April 28, 2014

How to run Jetty in embedded mode, for a Jersey based REST application

I wanted to be able to run Jetty in embedded mode and use Jersey for a simple REST service.  There was no single tutorial that helped me through all the steps.  I came up with the following after a lot of googling and cobbling together from various sources on the net.

I started off by creating a new Maven project in Eclipse, by choosing the following archetype
GroupId : org.mortbay.jetty.archetype
ArtifactId: jetty-archetype-assembler
Version: 7.5.1.v20110908
In Eclipse, (kepler) I had to add http://repo1.maven.org/maven2/archetype-catalog.xml as Remote Archetype catalog to be able to get the correct archetype.

I then changed the pom to reflect the latest versions available.

 <properties>  
  <jdk.version>1.7</jdk.version>  
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  <jersey.version>2.7</jersey.version>  
  <jetty.version>9.2.0.M0</jetty.version>  
  </properties>  
  <dependencies>  
  <!-- Servlet API -->  
  <dependency>  
   <groupId>javax.servlet</groupId>  
   <artifactId>javax.servlet-api</artifactId>  
   <version>3.1-b06</version>  
  </dependency>  
  <!-- Jetty -->  
  <dependency>  
   <groupId>org.eclipse.jetty</groupId>  
   <artifactId>jetty-webapp</artifactId>  
   <version>${jetty.version}</version>  
  </dependency>  
  <dependency>  
   <groupId>org.mortbay.jetty</groupId>  
   <artifactId>jsp-2.1-glassfish</artifactId>  
   <version>2.1.v20100127</version>  
  </dependency>  
  <dependency>  
   <groupId>org.glassfish.jersey.core</groupId>  
   <artifactId>jersey-server</artifactId>  
   <version>${jersey.version}</version>  
  </dependency>  
  <dependency>  
   <groupId>org.glassfish.jersey.containers</groupId>  
   <artifactId>jersey-container-servlet-core</artifactId>  
   <version>${jersey.version}</version>  
  </dependency>  
  <dependency>  
   <groupId>com.fasterxml.jackson.jaxrs</groupId>  
   <artifactId>jackson-jaxrs-json-provider</artifactId>  
   <version>2.2.2</version>  
  </dependency>  
  <dependency>  
   <groupId>org.slf4j</groupId>  
   <artifactId>slf4j-log4j12</artifactId>  
   <version>1.7.7</version>  
  </dependency>  
   </dependencies>  

The slf4j-log4j12 dependency allows you to use log4j for both jetty logging as well as application logging.

Packaging the application.
 <build>  
  <finalName>standalone-svc</finalName>  
  <resources>  
   <resource>  
    <directory>src/main/resources</directory>  
   </resource>  
   <resource>  
    <directory>src/main/webapp</directory>  
   </resource>  
  </resources>  
  <plugins>  
   <plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-compiler-plugin</artifactId>  
    <version>3.0</version>  
    <configuration>  
     <source>${jdk.version}</source>  
     <target>${jdk.version}</target>  
    </configuration>  
   </plugin>  
   <plugin>  
    <groupId>org.eclipse.jetty</groupId>  
    <artifactId>jetty-maven-plugin</artifactId>  
    <version>${jetty.version}</version>  
   </plugin>  
   <plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-jar-plugin</artifactId>  
    <version>2.4</version>  
    <executions>  
     <execution>  
      <id>package-jar</id>  
      <phase>package</phase>  
      <goals>  
       <goal>jar</goal>  
      </goals>  
     </execution>  
    </executions>  
   </plugin>  
   <plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-assembly-plugin</artifactId>  
    <version>2.4</version>  
    <configuration>  
     <descriptors>  
      <descriptor>src/main/assembly/assembly.xml</descriptor>  
     </descriptors>  
     <archive>  
      <manifest>  
       <mainClass>com.pramod.Main</mainClass>  
      </manifest>  
     </archive>  
    </configuration>  
    <executions>  
     <execution>  
      <phase>package</phase>  
      <goals>  
       <goal>single</goal>  
      </goals>  
     </execution>  
    </executions>  
   </plugin>  
  </plugins>  
 </build>  
The assembly.xml looks as follows;
 <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"  
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
   xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">  
  <id>standalone</id>  
  <formats>  
   <format>jar</format>  
  </formats>  
  <baseDirectory></baseDirectory>  
  <dependencySets>  
   <dependencySet>  
    <unpack>true</unpack>  
   </dependencySet>  
  </dependencySets>  
 </assembly>  
Executing mvn install, will generate jar file in the target directory, which can be executed by the command
java -jar <>.jar

Friday, June 22, 2012

Using perf4j to time methods

Perf4j is a great way to instrument your code to find out how long your methods are taking to execute.  I wanted a way to annotate my method and not have to pollute the code with startTimer, endTimer stuff.
Enter Perf4j's annotation based approach, implemented with aspectj AOP framework. Perfect!

Add the following maven dependencies to your pom
      <dependency>  
       <groupId>org.perf4j</groupId>  
       <artifactId>perf4j</artifactId>  
       <version>0.9.16</version>  
     </dependency>  
     <dependency>  
      <groupId>org.aspectj</groupId>  
      <artifactId>aspectjrt</artifactId>  
      <version>1.6.7</version>  
     </dependency>  
     <dependency>  
       <groupId>aspectj</groupId>  
       <artifactId>aspectjweaver</artifactId>  
       <version>1.5.4</version>  
     </dependency>  
     <dependency>  
       <groupId>commons-jexl</groupId>  
       <artifactId>commons-jexl</artifactId>  
       <version>1.1</version>  
     </dependency>  

Create the aop.xml file in the main/resources/META-INF/ folder.
 <?xml version="1.0" encoding="UTF-8"?>  
 <aspectj>  
  <!--  
   We only want to weave in the log4j TimingAspect into the @Profiled classes.  
   Note that Perf4J provides TimingAspects for the most popular Java logging  
   frameworks and facades: log4j, java.util.logging, Apache Commons Logging  
   and SLF4J. The TimingAspect you specify here will depend on which logging  
   framework you wish to use in your code.  
  -->  
  <aspects>  
   <aspect name="org.perf4j.log4j.aop.TimingAspect"/>  
   <!-- if SLF4J/logback use org.perf4j.slf4j.aop.TimingAspect instead -->  
  </aspects>  
  <weaver options="-verbose -showWeaveInfo">  
   <!--  
    Here is where we specify the classes to be woven. You can specify package  
    names like com.company.project.*  
   -->  
   <include within="com.yourpackage.*"/>  
   <include within="org.perf4j.log4j.aop.*"/>  
  </weaver>  
 </aspectj>  

Add the following to your log4j file
 <!-- Perf4J appenders -->  
   <!--  
    This AsyncCoalescingStatisticsAppender groups StopWatch log messages  
    into GroupedTimingStatistics messages which it sends on the  
    file appender defined below  
   -->  
   <appender name="CoalescingStatistics"  
        class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">  
     <!--  
      The TimeSlice option is used to determine the time window for which  
      all received StopWatch logs are aggregated to create a single  
      GroupedTimingStatistics log. Here we set it to 10 seconds, overriding  
      the default of 30000 ms  
     -->  
     <param name="TimeSlice" value="600000"/>  
     <appender-ref ref="fileAppender"/>  
     <!--  
      Note how the GraphingStatisticsAppenders have been attached to the  
      CoalescingStatistics here.  
     -->  
     <appender-ref ref="graphExecutionTimes"/>  
     <appender-ref ref="graphExecutionTPS"/>  
   </appender>  
   <!-- This file appender is used to output aggregated performance statistics -->  
   <appender name="fileAppender" class="org.apache.log4j.FileAppender">  
     <param name="File" value="/logs/perfStats.log"/>  
     <layout class="org.apache.log4j.PatternLayout">  
       <param name="ConversionPattern" value="%m%n"/>  
     </layout>  
   </appender>  
   <!--  
    This first GraphingStatisticsAppender graphs Mean execution times for the  
    firstBlock and secondBlock tags  
   -->  
   <appender name="graphExecutionTimes"  
        class="org.perf4j.log4j.GraphingStatisticsAppender">  
     <!-- Possible GraphTypes are Mean, Min, Max, StdDev, Count and TPS -->  
     <param name="GraphType" value="Mean"/>  
     <!-- The tags of the timed execution blocks to graph are specified here -->  
     <param name="TagNamesToGraph" value="firstBlock,secondBlock"/>  
     <appender-ref ref="graphsFileAppender"/>  
   </appender>  
   <!--  
    This second GraphingStatisticsAppender graphs transactions per second  
    for the firstBlock and secondBlock tags  
   -->  
   <appender name="graphExecutionTPS"  
        class="org.perf4j.log4j.GraphingStatisticsAppender">  
     <param name="GraphType" value="TPS"/>  
     <param name="TagNamesToGraph" value="firstBlock,secondBlock"/>  
     <appender-ref ref="graphsFileAppender"/>  
   </appender>  
   <!--  
    This file appender is used to output the graph URLs generated  
    by the GraphingStatisticsAppenders  
   -->  
   <appender name="graphsFileAppender" class="org.apache.log4j.FileAppender">  
     <param name="File" value="perfGraphs.log"/>  
     <layout class="org.apache.log4j.PatternLayout">  
       <param name="ConversionPattern" value="%m%n"/>  
     </layout>  
   </appender>  
   <!-- Loggers -->  
   <!--  
    The Perf4J logger. Note that org.perf4j.TimingLogger is the value of the  
    org.perf4j.StopWatch.DEFAULT_LOGGER_NAME constant. Also, note that  
    additivity is set to false, which is usually what is desired - this means  
    that timing statements will only be sent to this logger and NOT to  
    upstream loggers.  
   -->  
   <logger name="org.perf4j.TimingLogger" additivity="false">  
     <level value="INFO"/>  
     <appender-ref ref="CoalescingStatistics"/>  
   </logger>  

Add the @Profiled annotation to your code and off you go!
A file called perfStats.log is created with the stats.  There are parameters that can be tuned and graph based appenders that you can use as well.  For more details please check out perf4j Developer Guide

Update: 

If you are deploying to tomcat; to enable load time weaving; you will need to add 
-javaagent:<location_of_aspectjweaver.jar> to JAVA_OPTIONS.  

Tuesday, January 17, 2012

Create sample web app project in Eclipse using m2eclipse

Make sure you have m2eclipse installed from the update site http://m2eclipse.sonatype.org/sites/m2e
Key here is to also install the m2e-extras which allows for WTP integration.
Install m2e-extras from http://m2eclipse.sonatype.org/sites/m2e-extras

In Eclipse
    File -- New -- Other -- Maven -- Maven Project -- Next

In the New Maven Project dialog select
Group Id: org.apache.maven.archetypes
Artifact Id: maven-archetype-webapp

Provide a GroupId and ArtifactId for your project and thats all there is to it.