Archive for the ‘Java’ Category
Reducing JBoss’s Memory Footprint
I am working on a project to convert a handful of J2EE applications from an Oracle OC4J application (no longer supported) server to JBoss 5.1.0. Among the many challenges in the conversion is the fact that JBoss’s default profile has a significantly larger memory footprint than OC4J. In the past I have just accepted that Jboss uses over 400MB of heap space before you even deploy anything. This time however we were hoping to reuse the same hardware from the old application server with the new application server. When the test system started paging and eventually using up all of the physical memory available, we were forced to choose between ordering more memory and trying to tune jboss to reduce the memory footprint.
We ended up having a lot of success reducing the footprint through tuning. Bottom line: we reduced the memory footprint by 120MB, and the startup time from 53s to 24s
Here were the steps taken
| Heap Size (MB) | Used (MB) | Reduction in Used (MB) | ||
| Starting Heap | 419 | 314 | ||
| commented out debug level MBeans annotation in deployers.xml | 322 | 247 | 67 | |
| removed ejb3 services | 317 | 238 | 9 | |
| removed messaging folder & props | 310 | 238 | 0 | |
| removed seam & admin-console | 256 | 205 | 33 | |
| Removed xnio-deployer and xnio-provider | 256 | 203 | 2 | |
| removed ROOT.war | 256 | 203 | 0 | |
| removed management | 256 | 199 | 4 | |
| removed jbossws.sar | 256 | 193 | 6 |
The instructions for each step can be found : http://community.jboss.org/wiki/JBoss5xTuningSlimming
Notes on my environment and testing process:
- Windows XP, JDK 1.6.0_22,
- JBoss 5.1.0.GA. Xmx=512M , Xmx=256 (this is why heap didn’t drop below 256)
- I used jvisualvm to watch the heap and “used” memory values
- For the “Used” memory, I took the maximum observed value while JBoss was starting. If you understand that a time vs. memory usage graph follows a sawtooth pattern as objects are instantiated and garbage collected, then I took the value from the tip of the highest tooth.
No Fluff Just Stuff 2011, Madison, WI
I attended the No Fluff Just Stuff conference in Madison, WI this weekend. It was a great chance to learn the newest Java trends and share struggles in programming with people much like myself, even if most of them were cheeseheads. Here are some of my reflections on the state of Java tech post-conference:
-Java 7 is underwhelming, mostly because it will not have closures. It will however introduce enhancements to speed up Groovy, JRuby, and Scala
-If I read between the lines what features are in HTML and any of them are supported by Chrome, then I think that HTML5+Chrome could easily turn into a gaming platform!
-There is no question that Groovy is the “next big thing” for Java. Get on board.
-A java developer could easily add Hadoop to his resume (and dollars to his pocket), by learning Hadoop with Cascading. Hadoop-worthy scale data sets are available for free from amazon: http://aws.amazon.com/publicdatasets/
Grails is really cool. I wish there was a hosting platform available that was anything close to Heroku for Rails. I think it is unlikely that we will hear any good Startup stories with Grails for that reason.
Setting the Default Version of Java in Windows
You’re a java programmer on a Windows development environment. You fire up the command prompt and run “java -version”. It’s some JRE and its not even the version you want! Eclipse is throwing a fit. There’s no good way to figure out what path the “java.exe” you are executing lives in.
The most surefire way to solve this problem is take the java bin path (ex: C:\program files\Java\jdk1.6.0_07\bin) you want and prepend it to your System level PATH environment variable, as highlighted below. This will ensure that you are executing the java.exe from the expected java installation every time.

JPA Annotation Cheatsheet
Whenever I need need help configuring JPA annotations I turn to google, and I always find it difficult to find a good cheatsheet.
Well here is my favorite JPA annotation cheatsheet. Even though it says Oracle and Toplink it applies to any Spring/JPA/Hibernate technology stack:
http://www.oracle.com/technetwork/middleware/ias/toplink-jpa-annotations-096251.html
Oh yeah, and here’s my tip on using cascades: Never use CascadeType.ALL! Use MERGE, PERSIST, and maybe REMOVE if you want to cascade your deletes. CascadeType.ALL will result in poor performance and unintended consequences.
Configuring Jetty, Maven, and Eclipse together with Hot Swap
For over a year I’ve been developing a Java webapp in Hibernate with maven and Jetty. Recently I’ve figure out how to make them all play nice with each other. For too long I had to restart my application server, which takes upwards of 45 seconds, for any code changes to make it to my development server. This tutorial will show you how to setup Jetty in embedded mode, and using Eclipse, attach a debugger to enable True Hot Swap of code onto your Jetty server.
Environment Information:
JDK 1.5+
Eclipse 3.4.0
maven 2.0.10
m2eclipse 0.9.7 (maven plugin for eclipse)
Jetty 6.1.10
Spring
JPA,Hibernate
Java Project Versioning with perforce plus ant
I recently developed a useful ANT task to automatically increment a version number on your Java project when using perforce as your source control application. This task is intended to be run as part of an automated build (via cruisecontrol). It checks out version.properties and checks it back in after incrementing.
Notes:
- The task will look for the following files in the same directory as your build.xml. You should be able to figure out what parameters belong in each file by looking at the task. files: version.properties, buildnumber.properties, p4.properties
- In the lines where I print the full version number I have broken it up into two lines for display purposes. In practice you will want to keep it on one line.
<target name="create-label" depends="compile-src"> <copy todir="${ant.library.dir}" file="medremote_dev/tools/jakarta-oro-2.0.8.jar" overwrite="false" /> <property name="p4.properties" value="p4.local.properties" /> <property file="${p4.properties}" /> <property name="p4.port" value="${p4.port}" /> <property name="p4.client" value="${p4.client}" /> <property name="p4.user" value="${p4.user}" /> <!-- must supply password in globalopts when the perforce server uses sessions --> <property name="p4.globalopts" value="-P ${p4.password}" /> <property name="p4.path" value="{p4.path}" /> <echo>p4.path is ${p4.path}</echo> <!-- sync buildnumber.properties and version.properties for edit --> <p4sync view="${p4.path}/source/buildnumber.properties" force="true" globalopts="${p4.globalopts}" /> <p4sync view="${p4.path}/source/version.properties" force="true" globalopts="${p4.globalopts}" /> <!-- increment buildnumber.properties --> <chmod file="buildnumber.properties" perm="ugo+w" /> <attrib file="buildnumber.properties" readonly="false" /> <buildnumber file="buildnumber.properties" /> <tstamp /> <!-- Updates the version.properties file --> <property prefix="label" file="version.properties" /> <property name="new.version.major" value="${label.version.major}" /> <property name="new.version.minor" value="${label.version.minor}" /> <property name="new.version.iteration" value="${label.version.iteration}" /> <property name="new.version.build" value="${build.number}" /> <property name="new.version.drop" value="${label.version.drop}" /> <!-- update version.properties --> <chmod file="version.properties" perm="ugo+w" /> <attrib file="version.properties" readonly="false" /> <propertyfile file="version.properties"> <entry key="version.major" value="${new.version.major}" /> <entry key="version.minor" value="${new.version.minor}" /> <entry key="version.iteration" value="${new.version.iteration}" /> <entry key="version.drop" value="${new.version.drop}" /> <entry key="version.build" value="${new.version.build}" /> <entry key="version.date" value="${DSTAMP}${TSTAMP}" /> </propertyfile> <echo>Creating Label: ${new.version.major}.${new.version.minor}. ${new.version.iteration}.${new.version.build}"</echo> <p4change description="Increment build number via automatic build" globalopts="${p4.globalopts}" /> <!-- open buildnumber.properties and version.properties for edit (even though we already incremented it)--> <p4edit view="${p4.path}/source/buildnumber.properties" change="${p4.change}" globalopts="${p4.globalopts}" /> <p4edit view="${p4.path}/source/version.properties" change="${p4.change}" globalopts="${p4.globalopts}" /> <!-- submit properties files to source control after incrementing build --> <p4submit change="${p4.change}" globalopts="${p4.globalopts}" /> <!-- label the project --> <p4label name="FX${new.version.major}.${new.version.minor}. ${new.version.iteration}.${new.version.build}" desc="label created during automatic project build" view="${p4.path}/..." globalopts="${p4.globalopts}" /> </target>