woensdag 28 oktober 2009

Increase Heap Space size for maven on windows

When you get a Heap Space error when building with maven you can increase this heap space by setting MAVEN_OPTS.

On windows this is done by creating a mavenrc_pre.bat file in your %HOME% directory with this content:
set MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=128m

Similar there is a mavenrc_post.bat for everything you want to be executed after the build.

is org.richfaces.model.selection.ClientSelection causing PermGen OutOfMemoryError

In a previous post I got into the PermGen OutOfMemoryError, what it causes and how to fix it. The reason I got into this material is that I'm running into it myself with a richfaces application.

I'm also commenting on this issue about this problem. There you can see I was able to reproduce the problem with a simple application. Next step is to try fix it :D

woensdag 21 oktober 2009

java.lang.OutOfMemoryError: PermGen space on glassfish

Workaround

I get this PermGen space OutOfMemoryException sometimes when I do a lot of deployments on the Sun Java System Application Server 9.1_02 (build b04-fcs). The first hit when googling this error was this thread with a suggestion to increase memory heap size. But not only for the complete heap with the -Xmx argument because the PermGen space is only a fixed part of that memory, used for classloading. You can increment that specific part with the following arguments:

-Xmx=512m
-XX:MaxPermSize=256m
-XX:PermSize=256m

Understanding the problem

Even better is to find out where it leaks. But before we can do so we need to understand the problem.
What is PermGen space anyways? The memory in the Virtual Machine is divided into a number of regions. One of these regions is PermGen. It's an area of memory that is used to (among other things) load class files. The size of this memory region is fixed, i.e. it does not change when the VM is running. You can specify the size of this region with a commandline switch: -XX:MaxPermSize . The default is 64 Mb on the Sun VMs.

This is a comprehensive explanation of the cause:
To summarize, a new instance of custom Classloader is created by Application Server whenever a new application (.ear, .jar, .war) is deployed to the server, and this Classloader is used to load all the classes and resources contained in this application. Benefit in this approach is that, this way applications are self-contained and isolated from each other, and there are no conflicts between different applications. When an application is undeployed from server, its associated Classloader is also unloaded, and it is subject to garbage-collection by JVM.

As described in Frank's blog, there are situations in which Classloaders cannot be garbage-collected because of dangling references to them thru most unexpected places, and this will cause memory-leak in the PermGen space (a special section of heap). To find the cause of this problem, I used JDK 6.0's jmap and jhat utility to generate memory dump and analyze memory dump, respectively.

Fixing the problem

First of all we need to trigger the problem. That is by deploying your application and undeploying it again and then look for classes still loaded that shouldn't. When you find these classes you can track back for strong references from classes from another classloader. There are several tools for that. The easiest (as explained on the blog of Frank Kieviet) is to get the memory dump using jmap. For that we need to know the PID of the process, using jps:
jps
will return a list of PIDs and one of them is of your application server:
C:\Program Files\Java\jdk1.6.0_11\bin>jps
1000 jar
2204 Jps
2356 CLIMain
1796 org.eclipse.equinox.launcher_1.0.1.R33x_v20080118.jar
1824 PELaunch
For Glassfish it is called PELaunch. For other containers I have no idea.

Using that PID we can get a memory dump using jmap (included in JDK 6):
jmap -dump:format=b,file=leak 1824
Where 1824 is the PID of the container you're running and leak is the file where you want the dump be written to.

Then you can run jhat (included in JDK 6) to browse that dump:
jhat -J-Xmx512m leak
leak is the same file you've written the memory dump to. This will start a server you can reach by directing your browser to http://localhost:7000. 7000 is the default port. Now you can browse the classes and find those that are leaking. A goog idea is to look into the exclude weak refs links. Even better is to use the modified code of Edward Chou you can find on his blog. Then you can also list a hierarchy of classloaders with Show ClassLoader Hierarchy (added) and an extra link is added to show only strong links from classes in a different classloader: Exclude weak refs, filter enabled (added)

I now found a more visual approach at http://dev.eclipse.org/blogs/memoryanalyzer/2008/05/17/the-unknown-generation-perm/. It's an eclipse plugin that visualises the heap dump created with jmap (give the file a .hprof extension so it's recognized by this tool).

Resources

Check the following resources if you want to get into this problem:
http://blogs.sun.com/edwardchou/
http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java
http://blogs.sun.com/fkieviet/entry/how_to_fix_the_dreaded
http://mediacast.sun.com/users/Frank.Kieviet/media/JavaOne07-BOF9982-PermGen.pdf
http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html
http://blog.emptyway.com/2007/04/02/finding-memory-leaks-in-java-apps/

dinsdag 20 oktober 2009

format code in blog post using html, css and js

I have several code samples on this blog and I needed a way to display these with some kind of code highlighting. First queries returned me some blogs that only formatted the <pre> or <code> tag with css:
pre {
  background:#efefef;
  border:1px solid #A6B0BF;
  font-size:120%;
  line-height:100%;
  overflow:auto;
  padding:10px;
  color:#000000;
}
pre:hover {
  border:1px solid #efefef;
}
code {
  font-size:120%;
  text-align:left;
  margin:0;padding:0;
  color: #000000;
}
.clear { 
  clear:both;
  overflow:hidden;
}
And next I only needed to find a way to highlight code... Google has a code prettify project for that. It uses css as well but also javascripting. Read the instructions here. You need to add a reference in the header to the script and stylesheet like this:
<link href="prettify.css" type="text/css" 
  rel="stylesheet" />
<script type="text/javascript" 
  src="prettify.js"></script>
And then add the prettyPrint() function to the onload event of the body tag like this:
<body onload="prettyPrint();">

nullpointer for param inside commandlink

The problem started when I added this param to a commandlink like in the code below:
<h:commandLink 
  value="#{item.elementCombinedCode}" 
  action="#{elementFormController.prepareElementAction}">
<f:param name="elementNbr" 
  value="#{item.elementId}" />
</h:commandLink>
With Glassfish version 9.1_01 (build b09d-fcs) I then got this error:
java.lang.NullPointerException
at com.sun.faces.renderkit.RenderKitUtils.getCommandLinkOnClickScript(RenderKitUtils.java:934)
at com.sun.faces.renderkit.html_basic.CommandLinkRenderer.getOnClickScript(CommandLinkRenderer.java:295)
at com.sun.faces.renderkit.html_basic.CommandLinkRenderer.renderAsActive(CommandLinkRenderer.java:357)
at com.sun.faces.renderkit.html_basic.CommandLinkRenderer.encodeBegin(CommandLinkRenderer.java:165)
...
After some investigation I got to this issue stating that you would get this error when the given param value is null. Good news is that it's solved in following versions of glassfish. I quote:

The following will blow up:
<h:commandLink value="Go!">
    <f:param name="test" value="#{null}"/>
</h:commandLink>
The reason is that, while HtmlBasicRenderer.getParamList(UIComponent)
acknowledges that the parameter value may be null, and thus creates a
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.Param instance with a null
value if the parameter's value was null, the code in
RenderKitUtils.getCommandLinkOnClickScript dereferences the param.value property
without checking whether it is null:
for (Param param : params) {         
            sb.append(',');
            sb.append(param.name.replace("'", "\\\'"));
            sb.append(',');
            sb.append(param.value.replace("'", "\\\'"));            
        }          
Resulting in an NPE.

donderdag 15 oktober 2009

using JTrac as issue tracking system

We wanted some simple tracking system. Some out of the box and easy to use application. Because I have experience working with Trac this was my first choice. But on my current project we lack a Python installation so setup would require setting up a python environment first... Something similar in Java would be easier... and that would be JTrac indeed :D.

JTrac also has support for custom fields and a custom ticket workflow. Are very similar to Trac but in java an distributed as a war that we could deploy on our already running glassfish servers.

Until now we have only found one problem with version 2.1.0. Some tickets showed duplicate identities. It is already described in this topic so solution was fairly simple. And as it seems a new version have fixed this problem for ever.

I quote the solution:
I'm pretty confident this will be addressed in the next version, some work went into re-doing how the next sequence number is generated. You can check the SVN commit logs if you need more details.

Thanks all who posted information. It all helps. An update I received over e-mail from Maurizio (who reported the problem on restart) is at least in that scenario - the problem is fixed.

New installations of JTrac will also enforce a unique constraint at the database level - for the combination of 2 columns on the "items" table. Existing users can easily do this on their existing databases.

The columns on the "items" table are "space_id" and "sequence_number"

For HSQLDB and MySQL you can add a constraint as follows:
alter table items add constraint con_items_space_seq unique (space_id, sequence_num);
This command will of course fail if the table still contains duplicates. To find duplicates, you can run this query:
select a.id from items a, items b where a.space_id = b.space_id and a.sequence_num = b.sequence_num and a.id > b.id;
You can select more columns in the above query to get more info as to which rows are duplicated. But the above query can be easily used as a subquery to delete the duplicate records. To take care of referential integrity, you have to delete the history table entries first:
delete from history where item_id in (
select a.id from items a, items b where a.space_id = b.space_id and a.sequence_num = b.sequence_num and a.id > b.id
);
and then:
delete from items where id in (
select a.id from items a, items b where a.space_id = b.space_id and a.sequence_num = b.sequence_num and a.id > b.id
);
And now you can add the unique constraint.