Thursday, 26 January 2012

Tomcat 7 Service : start in debug mode

Hit a problem today, doing a really simple tutorial app, so decided to debug Tomcat 7 remotely from Eclipse. I started looking on the web, and almost everything refers to earlier versions of Tomcat.
The ones which did mention running Tomcat 7 didn't appear to be using it as a service, so I had a quick look at the Tomcat site to see if there were any how-to's.

From there, the answer was simple.

From the command line :
H:\Tomcat 7.0\bin\tomcat7 //TS//Tomcat7 -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n

When started like this, Eclipse was able to connect using it's standard remote debug config.

Monday, 12 September 2011

Multi module build in Maven




I've been at this one for a couple of days, so decided to post this here for future reference. My aim is to create a jar file, with a sub directory called lib, and have all the 3rd party dependencies in there, e.g

    project.jar
      /lib/spring-beans-3.0.5.RELEASE.jar
      /lib/logback.jar
      /lib/commons-cli-1.1.jar

The project looks like :
    adapter
        core
        ftp
        web-service

At this stage, I'm putting demo code together for different sprints, so only wanted some jar files to run from the command line. Maven Assembly is the package designed to do this, so I read the Apache Maven Assembly information, and the Sonatype manual on assemblies, but the examples on both were mixed, and it wasn't clear to me how to do get this working.. All of the material here was all written using Maven Assembly 2.2.1.

I got some basic examples going quickly, but then got bogged down adding a custom assembly descriptor (see below).
The recommendation in both references is to add another module to the project, so it looks like :

    adapter
        core
        ftp
        web-service
        distribution

Below is the example code I'm currently using to get this : it will be refined, and as it get's better, I'll edit this post.

Parent pom :
Once you move to a multimodule build, make sure you move the plug in information out of the parent pom.xml, and ensure it exists only in the new distribution module's pom.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <name>proj</name>
    <groupId>com.proj.adapter</groupId>
    <artifactId>project</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <description>
        ..
    </description>
    <modules>
        <module>proj-core</module>
        <module>proj-ftp</module>
        <module>proj-ws</module>
        <module>distribution</module>
    </modules>
    <properties>
        ....
        <maven.assembly.version>2.2.1</maven.assembly.version>
        <plexus.utils.version>1.1</plexus.utils.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>${project.groupId}</groupId>
                <artifactId>proj-core</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        ..
    </dependencies>
    <build>
        <pluginManagement>
        ..
        </pluginManagement>
    </build>

</project>

Distribution module pom.xml
The main items here are :
1. Identify the location of the custom assembly descriptor (shown in bold),
2. Bind the lifecycle in the executions tag. Some of the examples I saw had the configuration within the execution tag, but I never got this to work,


 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <groupId>com.proj.adapter</groupId>
  <artifactId>adapterProject</artifactId>
  <version>1.0-SNAPSHOT</version>
 </parent>
 <artifactId>dist</artifactId>
 <packaging>pom</packaging>
 <name>Distribution</name>
 <dependencies>
  <dependency>
   <groupId>com.proj.adapter</groupId>
   <artifactId>adapterProject-core</artifactId>
   <version>1.0-SNAPSHOT</version>
  </dependency>
 </dependencies>
 <build>
  <finalName>adapterProject</finalName>
  <plugins>
   <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>${maven.assembly.version}</version>
    <configuration>
     <descriptors>
      <descriptor>src/main/assembly/bin.xml</descriptor>
     </descriptors>
    </configuration>
    <executions>
     <execution>
      <id>distro-assembly</id>
      <phase>package</phase>
      <goals>
       <goal>single</goal>
      </goals>
     </execution>
    </executions>
   </plugin>
  </plugins>
 </build>
</project>





Custom assembly descriptor
This is just an xml file, referenced from the distribution modules pom.
For a good few hours this was the bit that got me, every attempt to build returned an error message that one file had to be included, and I couldn't see where I'd gone wrong on my dependencies.  Eventually I cracked it, and have highlighted it here.
The examples I saw used

<includes>
    <include>*-ws</include>
   </includes>
and other similar examples. Some didn't have the useAllReactorProjects included, but, eventually I got the distribution module to get the correct dependencies and find the file using the snippet below.

<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>bin</id>
 <formats>
  <format>dir</format>
 </formats>
 <moduleSets>
  <moduleSet>
   <useAllReactorProjects>true</useAllReactorProjects>
   <includes>
    <include>${project.groupId}:adapterProject-core</include>
   </includes>
   <binaries>
    <outputDirectory>/</outputDirectory>
    <unpack>false</unpack>
    <includeDependencies>true</includeDependencies>
    <dependencySets>
     <!--  create the location of the core jar-->
     <dependencySet>
      <includes>
       <include>${project.groupId}:adapterProject-core</include>
      </includes>
      <useTransitiveDependencies>false</useTransitiveDependencies>
      <outputDirectory>/</outputDirectory>
      <unpack>true</unpack>

     </dependencySet>
     <!--  create the lib directory for the supporting jars -->
     <dependencySet>
      <excludes>
       <exclude>${project.groupId}:adapterProject-core</exclude>
      </excludes>
      <useProjectArtifact>false</useProjectArtifact>
      <useTransitiveDependencies>false</useTransitiveDependencies>
      <outputDirectory>lib</outputDirectory>
     </dependencySet>
    </dependencySets>
   </binaries>
  </moduleSet>
 </moduleSets>
</assembly>



Hope this helps someone else struggling with this.

Wednesday, 17 August 2011

UMLet - UML Tool for Fast UML Diagrams | Eclipse Plugins, Bundles and Products - Eclipse Marketplace

UMLet - UML Tool for Fast UML Diagrams | Eclipse Plugins, Bundles and Products - Eclipse Marketplace

Very nice tool for simple UML diagramming, that I could then export to Word. I ran it as an Eclipse plug in, and would definitely use this again. There's almost no learning curve, the interface is simple. I thought of BoUML as a good tool, but this is even easier to use.

Thursday, 14 July 2011

Home Computing 101

After a recent IT disaster, the need to back up to more than one location has been driven home pretty brutally. After some work, and some help, I did manage to get back most of what I had before. The biggest loss has been the source code from previous jobs : some of that was quite neat, and always a useful reference.
So backups are back on a weekly schedule to alternating locations : this time one to an external hard drive on Sunday, and one from the primary computer to the server on a Saturday. I will need to organize the backups for the server's repository as well. Backups are through Genie 9's Genie Backup Manager Home 8.0. It's easy enough to use, but haven't tried restoring from it yet.

As part of the general effort to restore the PC, I decided to partition the C drive on the primary PC into 3 areas : C: for Windows and general family use, H: for development work and data, and I: which will eventually host Ubuntu. I use Ubuntu a bit at work, but it'd be useful to get more time with it.
This proved to a useful guide to partitioning a hard drive. From there I looked at SwissKnife, but in the end went for Easeus Partition Master Home Edition. I can't recommend it enough : easy to use, pretty quick, nice UI. If anyone knows any drawbacks on this tool, let me know, because at the moment, I'm sold.

Thursday, 5 May 2011

Tomcat 7 Windows Service memory management - a correction

In an earlier post, I made a serious mistake, so this should go some way to correcting it.

First Hudson Run

My first run of Hudson on Tomcat 7 led to the infamous error :
FATAL: PermGen space java.lang.OutOfMemoryError: PermGen space
Not surprising, given the spec of the machine I'm using, but still a pain.
Using VisualVM, it shows the PermGen size to be still at the default 64MB size. Attempts to monitor the build process weren't successful as the entire machine ground to a halt.


Previously on Tomcat 5/6, I'd've set the catalina.bat or catalina.sh file to contain the memory management options, but this file doesn't exist in Tomcat 7. This was new to me.

Tomcat itself isn't helpful with Permgen, as although it's possible to find the inital and maximum heap memory size on the Manager App, Server Status tab, it doesn't show the permgen size.


There are some really good sites listing the mechanics of setting Tomcat's memory.
WEBMAP is for a Tomcat running on jdk 1.3, but the step by step process to figuring out which parameters are useful is useful.

CATALINA_OPTS vs JAVA_OPTs
I found some sites that suggested setting the OPTS as a Windows environment variable. Several blogs and sites suggest using JAVA_OPTS. I'd caution on this, as although others got it to work, JAVA_OPTS are used by other applications (JBoss in particular was mentioned), not just Tomcat. I decided to stick with CATALINA_OPTS.
But, when I tried setting the environment variable, and restarting Tomcat, I didn't see an increase in the Heap size. I'm not saying it doesn't work, but I couldn't get it to work. Combined with the fact that I didn't like the idea of doing it this way as it seems to be scattering the configuration across a number of places, I didn't really put any further effort into making this work.

Setting memory options on Tomcat

Remember -Xms and -Xmx only set the heap size. These are easy enough to set through the Monitor Tomcat GUI, on the Java tab as the Initial Memory Pool (equivalent to -Xms) and the Maximum Memory Pool (-Xmx).









To set the Permgen size, you need either -XX:PermSize=XXXm or -XX:MaxPermSize=XXXm, and see WEBMAP for a more detailed review of each of these. Again, this can be set on the Java tab of the Monitor Tomcat GUI, this time as a Java Option, I went for -XX:PermSize=128m.

The difference can be seen on the next screenshot, again of the MonitorVM application. Heap size has gone from 67MB to 134MB.


Effect of all of this ?

I now have a Hudson build that doesn't crash Tomcat either during or immediately after each run. Heap size during a build is about the 75MB mark. Maybe now I can start doing some coding ...

Useful references

In addition to those mentioned above, I found these two references from http://www.skill-guru.com to be useful :
Setting Heap Size
Setting Permgen Size