Home/Tag: Java

Session and Memory Leak on Wildfly 10

I recently re-wrote 10MinuteMail, my secure temporary email service, updating it from Seam 2 and JBoss 4.2 to Deltaspike and Wildfly 10.  Unfortunately I noticed a memory leak in the JVM.  During beta testing, the JVM heap usage would slowly grow, over 1-2 weeks until it reached an OOM (out of memory condition).

Memory Leak in the Old Gen on Wildfly 10

I performed analysis on heap dumps taken at various stages of memory consumption and discovered that the issue was HttpSessionImpl objects being held onto by the com.sun.faces.application.WebappLifecycleListener’s activeSessions property.  Since 10MinuteMail does some “manual” session expiration and management, and the new application is AJAX heavy, I figured I was doing something wrong.  But thanks to some great support on the forums, I soon learned that there is a bug in the Undertow sub-system that ships with Wildfly 10.0.0.FINAL which keeps old sessions around, causing a memory leak – 

[UNDERTOW-657] HttpSession never removed from activeSessions – JBoss Issue Tracker

The fix is to replace the Undertow modules that come with Wildfly 10 with the latest stable release versions.  You can find more details here –

Now my application works as expected with no memory leak or abnormal numbers of session objects.

Terrible Code

request.setParameter("qualifySkus", getSkusRepository(d, cItem));

  1. “qualifySkus” is confusing. Is it an array/list/collection of “qualifiedSKUs” or a flag that’s a result of “qualifyingSkus” or….
  2. “qualifySKus” should be a constant with a nice comment, not an in-line String.
  3. The method getSkusRespository seems like it would return a catalog repository, doesn’t it? Instead it takes in a List of String SkuIds, loads up the corresponding SKU RepositoryItems, removes any that have the property “isLive” set to false, and removes any that have a current inventory stock level of zero. It then returns an ArrayList of those filtered SKU RepositoryItems. Perhaps a better name might be “getLiveInStockSKUs”?
  4. What on earth is “d”? Even looking at the full code of this class, it’s very difficult to tell what d is meant to contain. It’s actually a List of Strings of SkuIds that are qualifying skus for a given promo. “qualifiedSkus” would be a better name.
  5. cItem is a commerce item. However it’s not actually used by the getSkusRepository method at all. There’s no reason to pass it in.
  6. This line is in an ATG droplet and shoves the result of the getSkusRepository method into a request param before servicing an oparam. However, as you can see, it doesn’t inspect the output of the method. As I explained above, the method actually filters a list of SKUs based on isLive and current inventory state. It’s very possible that there will be no live and in-stock SKUs, and the param’s value will be null or an empty list. In that case, we’d actually want to render a different oparam, which is defined and called elsewhere, but not here. Validate your output!

That’s six issues in one line. Please don’t write code like this.

Eclipse Auto Complete Templates for ATG

Eclipse has an often under-utilized feature called Templates. You’ve probably used the built in templates when Eclipse auto-completes for loops or try-catch blocks, etc… However, you can create your own templates for commonly used chunks of code. This can save you a lot of time, and more importantly can facilitate you writing better quality code.

ATG Eclipse Templates

ATG Eclipse Templates

By making commonly used code blocks available with a couple of keystrokes it is much easier to write best practices code, that otherwise you might shortcut around.

You can view, import, and create new templates by going to Eclipse’s Preferences, then opening Java->Editor->Templates. Each Template has a Name, this is what triggers it for auto-complete so making this simple and unique is good, a Description, a Context, a checkbox to Automatically insert, and then the Pattern which is the code that will get inserted for you. Within the Pattern you have access to a substantial number of variables, such as the current class or method name, variables, method arguments, dates, etc… which allow you do some very useful things.

For ATG coding I’ve created nine Templates for common code blocks.

My templates isBlank and isNotBlank create if blocks based on ATG’s StringUtils.isBlank method, which checks for null, empty, or blank Strings. Checking Strings is something that I do all the time (validating user input, query params, etc…) so being able to do it in a few keystrokes is very useful.

[java] ls.isBlank(${cursor})) {


I have three templates for ATG Performance Monitor operations. Adding in ATG Performance Monitor hooks when you’re coding can make diagnosing performance problems later much easier. Using templates means you don’t have to remember the syntax or even type in the class and method names:

[java] PerformanceMonitor.startOperation(“${enclosing_type}”, “${enclosing_method}”);[/java]

I also have four templates for the primary ATG logging methods with the respective if blocks needed to prevent unnecessary String concatenations.

[java] if(isLoggingDebug()) {
logDebug(“${enclosing_type}.${enclosing_method}:” + “${cursor}”);

I’ve exported these nine ATG templates so you can easily import and start to use them.
Eclipse ATG Coding Templates.

What templates have you created?

JForum SSO (single sign-on) and Atlassian Crowd

Over at our new ATG Developer Community site, we’re using Atlassian Crowd to manage our user accounts, groups, and single sign-on (SSO) between Jira, Confluence, to manage Subversion authentication, and to handle the forums (JForum) user accounts.

There was an example on how to integrate JForum and Crowd, which works pretty well. When you login to the forum, it checks Crowd and creates a local account if needed and logs you in.

However, we want single sign-on (SSO) so that our users don’t need to login to the forums separately. We also want group membership in Crowd to be reflected in JForum to allow us to manage permissions based on Crowd managed groups.

I’ve written a JForum SSO implementation that ties into Crowd that I’m going to share here. It’s version 1.1 (just added group sync), but it seems to work nicely.

Download the zip file here:

unzip it into your jforum/WEB-INF/classes/ directory.

You have to install the crowd client jar, and the file.

You may also need to install the xfire jars if you get errors. I did.

Then you need to setup the sso configuration in the jforum/WEB-INF/config/

like this:

sso.implementation = com.digitalsanctuary.jforum.CrowdSSO
sso.redirect = your crowd managed app login page

That last flag should be set to true if you would like the user’s groups synced from Crowd to JForum at auth time. This takes a second, so I made it optional. It does not push JForum group membership info to Crowd, it just syncs Crowd data down, as Crowd should be your master directory for that type of data.

The source code is available here for now:


Added a full downloadable module and installation instructions here:

How To Resize Uploaded Images Using Java – Better Way

Based on helpful comments from Matt on this previous post:

How To Resize Uploaded Images Using Java

I have upgraded the image resizing code. The results are noticeably better in quality, even at thumbnail sizes. I wanted to share the completed new code, in case anyone needs it.

Again, thanks to Matt S. for his pointers.

[java] /**
* The JAI.create action name for handling a stream.
private static final String JAI_STREAM_ACTION = “stream”;

* The JAI.create action name for handling a resizing using a subsample averaging technique.
private static final String JAI_SUBSAMPLE_AVERAGE_ACTION = “SubsampleAverage”;

* The JAI.create encoding format name for JPEG.
private static final String JAI_ENCODE_FORMAT_JPEG = “JPEG”;

* The JAI.create action name for encoding image data.
private static final String JAI_ENCODE_ACTION = “encode”;

* The http content type/mime-type for JPEG images.
private static final String JPEG_CONTENT_TYPE = “image/jpeg”;

private int mMaxWidth = 800;

private int mMaxWidthThumbnail = 150;


* This method takes in an image as a byte array (currently supports GIF, JPG, PNG and
* possibly other formats) and
* resizes it to have a width no greater than the pMaxWidth parameter in pixels.
* It converts the image to a standard
* quality JPG and returns the byte array of that JPG image.
* @param pImageData
* the image data.
* @param pMaxWidth
* the max width in pixels, 0 means do not scale.
* @return the resized JPG image.
* @throws IOException
* if the image could not be manipulated correctly.
public byte[] resizeImageAsJPG(byte[] pImageData, int pMaxWidth) throws IOException {
InputStream imageInputStream = new ByteArrayInputStream(pImageData);
// read in the original image from an input stream
SeekableStream seekableImageStream = SeekableStream.wrapInputStream(imageInputStream, true);
RenderedOp originalImage = JAI.create(JAI_STREAM_ACTION, seekableImageStream);
((OpImage) originalImage.getRendering()).setTileCache(null);
int origImageWidth = originalImage.getWidth();
// now resize the image
double scale = 1.0;
if (pMaxWidth > 0 && origImageWidth > pMaxWidth) {
scale = (double) pMaxWidth / originalImage.getWidth();
ParameterBlock paramBlock = new ParameterBlock();
paramBlock.addSource(originalImage); // The source image
paramBlock.add(scale); // The xScale
paramBlock.add(scale); // The yScale
paramBlock.add(0.0); // The x translation
paramBlock.add(0.0); // The y translation

RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_RENDERING,

RenderedOp resizedImage = JAI.create(JAI_SUBSAMPLE_AVERAGE_ACTION, paramBlock, qualityHints);

// lastly, write the newly-resized image to an output stream, in a specific encoding
ByteArrayOutputStream encoderOutputStream = new ByteArrayOutputStream();
JAI.create(JAI_ENCODE_ACTION, resizedImage, encoderOutputStream, JAI_ENCODE_FORMAT_JPEG, null);
// Export to Byte Array
byte[] resizedImageByteArray = encoderOutputStream.toByteArray();
return resizedImageByteArray;