Archive for the ‘Programming’ Category

JPS and VisualVM on Windows

Sunday, October 4th, 2009

At several stops on the NFJS tour, I’ve been asked about some of the minor issues in running JPS and VisualVM on the Windows platform. The primary problem is that the processes in JPS and VisualVM are listed as:

<Unknown Application> (pid ###)

I have been successful in working around this by renaming the hsperfdata temp directory as noted in a separate thread on the Sun forums.

Encrypted SCM Passwords in Maven

Friday, August 28th, 2009

A little late night hacking and I was able to get encrypted passwords to work in the Maven SCM plugin with Maven 2.2 based on the prodding of Kurt Tometich, an NFJS attendee, and his JIRA bug# SCM-495. Previously, this encryption feature only worked for Wagon providers (the connectors for uploading artifacts), not for SCM providers, contrary to some blog comments.

It was quite the effort. After a few minutes, I found the code in DefaultMaven.java that performed the decryption. Now, I thought, “just implement a similar call in AbstractScmMojo.java right?” I harbor a bit of angst for the fact that the JIRA isn’t Fisheye-connected to the source code repository, so finding the files changed for a given defect is much harder than it should be.

The Maven Mojo Developer Cookbook did offer a bit of insight (though syntactically off a bit on the container.getLookupRealm()) on how to get a handle to the container and look up the security provider, DefaultSecDispatcher.java.

SecDispatcher sd = null;

try {
  sd = (SecDispatcher)container.lookup( SecDispatcher.ROLE, &amp;amp;quot;maven&amp;amp;quot; );
}

There was even the fabled “java.lang.ClassCastException: org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher cannot be cast to org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher” at one point. Oh nuts. Not the classloader scoping issue, please…

The trick on the classloader is that the DefaultSecDispatcher class is available via a dependency to plexus-sec-dispatcher, but also included (repackaged) in the Maven core distribution maven-2.2.0-uber.jar. So the SCM provider project’s dependency on plexus-sec-dispatcher has to be scoped as <provided> for compilation of the maven-scm-plugin.

Lots of learning about the Maven code base occurred. The only interesting finding was how, instead of putting the decryption on the accessor (getter) of password from the settings data structure, it is put in each place it is attempted to be used (e.g. the Wagon “dispatcher”, and now the SCM “dispatcher”). I’ll bring up a refactoring of that with the Maven IRC folks…

BTrace in VisualVM on the Mac

Tuesday, July 21st, 2009

The BTrace plugin for VisualVM, a tool that I love to showcase at No Fluff Just Stuff and user group events, has been updated to version 0.2.2. This solves an issue that prevented it from working on a Mac. Be sure to uninstall any prior version from your VisualVM prior to installing 0.2.2 to get the full benefit of the fix.

Btrace2.png

BTrace1.png

Java 1.6 Memory Tools on the Mac, Part II

Saturday, July 11th, 2009

I’ve been battling getting jmap working properly on a new Mac. I followed the invaluable instructions my NFJS colleague, Ken Sipe, provided for the Rhino engine inclusion. However, I was still encountering an odd issue where I couldn’t get jmap to attach to a Java process.

First, I would start a simple helloworld Java application.

java com.ambientideas.HelloWorldJava
Hello Java World!

Picture 1.png

Then I would get the PID:

jps
11554 HelloWorldJava
11573 Jps

Then I tried to jmap it, but got the following error

jmap -heap 11554
Attaching to process ID 11791, please wait...
attach: task_for_pid(11791) failed (5)
Error attaching to process: Error attaching to process, or no such process

So I thought, “These memory tools often require root access, so I’ll sudo it.” When I did, I got the following equally cryptic error:

sudo jmap -heap 11791
Attaching to process ID 11791, please wait...
Exception in thread main java.lang.RuntimeException: gHotSpotVMTypes was not initialized properly in the remote process; can not continue
at sun.jvm.hotspot.HotSpotTypeDataBase.readVMTypes(HotSpotTypeDataBase.java:111)
at sun.jvm.hotspot.HotSpotTypeDataBase.&amp;amp;amp;amp;amp;amp;lt;init&amp;amp;amp;amp;amp;amp;gt;(HotSpotTypeDataBase.java:68)
at sun.jvm.hotspot.MacOSXTypeDataBase.&amp;amp;amp;amp;amp;amp;lt;init&amp;amp;amp;amp;amp;amp;gt;(MacOSXTypeDataBase.java:35)
at sun.jvm.hotspot.bugspot.BugSpotAgent.setupVM(BugSpotAgent.java:560)
at sun.jvm.hotspot.bugspot.BugSpotAgent.go(BugSpotAgent.java:481)
at sun.jvm.hotspot.bugspot.BugSpotAgent.attach(BugSpotAgent.java:319)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:146)
at sun.jvm.hotspot.tools.JMap.main(JMap.java:128)

I though, “Hmmmm, this looks a lot like a java version mismatch. Let’s check which java version I’m running.” I had javac compiled the HelloWorld against Java 6, so was expecting a matching java. I made a quick stop into the Java Preferences pane. Yup. Java 6 set as the first-priority choice.

Picture 2.png

Let’s check the command line too…

java -version
java version 1.6.0_13
Java(TM) SE Runtime Environment (build 1.6.0_13-b03-211)
Java HotSpot(TM) 64-Bit Server VM (build 11.3-b02-83, mixed mode)

Excellent. Just what I expected. Java 6. But a little doubt crept into my mind. What if the sudo’ed invocation were finding a different Java. That didn’t sound plausible, but yet was still worth checking out.

sudo java -version
java version 1.5.0_19
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_19-b02-304)
Java HotSpot(TM) Client VM (build 1.5.0_19-137, mixed mode, sharing)

Aha! There’s the culprit. So somehow, sudo’ed commands are running Java 5, even though I’ve set a preference for 6 in my profile. I searched the web high and low for a way to specify the Java version for “sudo” specifically, but could find no trace. I even tried the -E flag to maintain the caller’s environment variables, as is possible on Linux distributions. Not implemented on Mac.

I did a quick check of my path and a “which java”. Both ultimately routed to Java 6. I also had JAVA_HOME and JAVA_VERSION set just fine.

set | grep JAVA
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home
JAVA_VERSION=1.6

echo $PATH
/Applications/Dev/btrace/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:
/usr/X11/bin:./:
/Users/mccm06/scripts:/Applications/Dev/apache-ant/bin:
/Applications/Dev/apache-maven/bin

So I turned to harness the wisdom of one of the really smart guys (that uses a Mac) I’m privileged to hang out with in Denver, Fred Jean. Fred said, “Try adding the 1.6 java explicitly to the front of your path rather than letting Java Preferences pane be the sole controller.” I opened up ~/.bash_profile (alternatively you could edit ~/.bash_rc)and slammed in the following:

export PATH=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Commands:$PATH

I opened a new terminal to pick up the shell changes. Then I started checking if this fixed the issue in reverse order, starting with the sudo:

sudo java -version
java version 1.6.0_13
Java(TM) SE Runtime Environment (build 1.6.0_13-b03-211)
Java HotSpot(TM) 64-Bit Server VM (build 11.3-b02-83, mixed mode)

200907110802.jpg

Looking good! Now let’s get back to our core goal, jmap.

200907110804.jpg

sudo jmap -heap 5951
Attaching to process ID 5951, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 11.3-b02-83
using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC
Heap Configuration:
    MinHeapFreeRatio = 40
    MaxHeapFreeRatio = 70
    MaxHeapSize = 88080384 (84.0MB)
    NewSize = 21757952 (20.75MB)
    MaxNewSize = 43581440 (41.5625MB)
    OldSize = 64159744 (61.1875MB)
    NewRatio = 7
    SurvivorRatio = 6
    PermSize = 21757952 (20.75MB)
    MaxPermSize = 88080384 (84.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
    capacity = 19070976 (18.1875MB)
    used = 2351616 (2.24267578125MB)
    free = 16719360 (15.94482421875MB)
    12.330863402061855% used
Eden Space:
    capacity = 16384000 (15.625MB)
    used = 2351616 (2.24267578125MB)
    free = 14032384 (13.38232421875MB)
    14.353125% used
From Space:
    capacity = 2686976 (2.5625MB)
    used = 0 (0.0MB)
    free = 2686976 (2.5625MB)
    0.0% used
To Space:
    capacity = 2686976 (2.5625MB)
    used = 0 (0.0MB)
    free = 2686976 (2.5625MB)
    0.0% used
concurrent mark-sweep generation:
    capacity = 64159744 (61.1875MB)
    used = 0 (0.0MB)
    free = 64159744 (61.1875MB)
    0.0% used
Perm Generation:
    capacity = 21757952 (20.75MB)
    used = 4716880 (4.4983673095703125MB)
    free = 17041072 (16.251632690429688MB)
    21.678878600338855% used

Thanks to a combination of Ken Sipe, Fred Jean, a few good guesses and some investigative work, the problem is solved! I’m longwindedly calling this the “java version is different for sudo-initiated processes on Mac” so that the next person Googling for this using similar keywords will hopefully find this tutorial.

As a closing note, I often get asked how I set my environment variables for Java so that Spotlight-launched, Quicksilver-launched, Dock-launched, and Terminal-launched processes can all see the variables (yes, there’s some odd pitfalls about that on a Mac due to the process parents being different). The short answer is to create a text file called /private/etc/launchd.conf and put the following (applicable portions, based on your tool usage) contents in it:

setenv JAVA_VERSION 1.6
# A) Some process-launchers will cause their child to default to 1.5 if using /Library/Java/Home
# even if Java Preferences pane says 1.6 at the top
# setenv JAVA_HOME /Library/Java/Home
# B) Alternate: Force Java 1.6 as Java Home
setenv JAVA_HOME /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home
setenv GROOVY_HOME /Applications/Dev/groovy
setenv GRAILS_HOME /Applications/Dev/grails
setenv NEXUS_HOME /Applications/Dev/nexus/nexus-webapp
setenv JRUBY_HOME /Applications/Dev/jruby
# Set up Ant
setenv ANT_HOME /Applications/Dev/apache-ant
setenv ANT_OPTS -Xmx512M
# Set up Maven
setenv MAVEN_OPTS -Xmx1024M
setenv M2_HOME /Applications/Dev/apache-maven

As we have learned the hard way, the only pitfall is that the java version specified in launchd.conf is not honored by sudo’ed java invocations.

Drop me an email if you’ve seen this issue and this tutorial helps you solve it.

Script for finding a class inside a directory of JARs

Sunday, June 14th, 2009

In the spirit of automating anything I’ve done more than twice manually, here’s an incredibly simple yet useful little script to recursively search a tree of JARs for a class file. I most often use this against a local Maven repository.

#!/bin/sh

#Example Usages:
# findjars com/ambientideas/SuperWidget
# findjars AnotherWidget

CLASSNAMETOFIND=&amp;quot;$1&amp;quot;

echo &amp;quot;Searching all JARs recursively...&amp;quot;
for eachjar in `find . -iname &amp;quot;*.jar&amp;quot;`
do
  #echo &amp;quot;Searching in $eachjar ...&amp;quot;
  jar tvf $eachjar | grep $CLASSNAMETOFIND &amp;gt; /dev/null
  if [ $? == 0 ]
  then
    echo &amp;quot;******* Located &amp;quot;$CLASSNAMETOFIND&amp;quot; in $eachjar *******&amp;quot;
  fi
done

DZone Maven RefCard Released

Friday, May 29th, 2009

MavenRefCard.jpgI’m very pleased to announce that my DZone Maven RefCard was released this week ahead of schedule, and JavaLobby did a little introductory interview for the launch. A handful of folks contributed to the early alpha reviews and I want to acknowledge their inputs: Ken Sipe, Tim O’Brien, Chris Maki, Tim Berglund, and Jason van Zyl.

The timing was great, as I did a Mastering Maven talk at the San Diego Java Users Group (SDJUG) on Tuesday night. A handful of the attendees came with printed copies of the RefCard in hand!

I’m always looking for ways to contribute to the Maven community, and this was by far the most fun I’ve had building materials to promote this unique Convention over Configuration build tool.

Git on Windows + Maven Gits on the Bleeding Edge

Saturday, April 25th, 2009

Git, the oft-referred to as “Linux, Rubyists, and Cool Kids source code control system”, is gaining ground so fast that there’s not enough room in this post to mention all the traction and good press it is achieving. Yet, a common comment I hear over lunches and cubicle walls is

Git doesn’t have good support on Windows yet.

I politely disagree.

While the methods for putting Git on Windows have a slight variance from that of putting it on Mac or Linux, I have seen no real compatibility issues in my near daily use of it on all three aforementioned platforms. Is there still room for it to get better on Windows though? Definitely!

The next lament I hear is

If only there were a Tortise-like UI for Git.

Let me also put that to rest and direct you to the TortiseGit homepage. While TortiseGit is still a work in progress, I’ve seen a handful of folks already putting it to productive daily use. And if you don’t like TortiseGit, then try GitSafe. And if you are using IntelliJ, support is built right into v8.1, Eclipse has eGit as an official Eclipse project now, and NetBeans has an issue open and some ongoing work for support which, awesomely consumes parts of eGit (JGit Libs) from Eclipse.

And just to share the “Peanutbutter in my Chocolate” favorite story of the week, Maven is moving to Git in many directions at once:

  1. I asked Jukka Zitting of Apache to mirror the Maven SVN trunks to Git. 36 hours later, it was done. What an amazing team player Jukka is.
  2. Maven: The Definitive Guide has moved its canonical repository to GitHub. Fork, contribute, and issue pull requests to Sonatype at will!
  3. Jason van Zyl, the founder of Maven, has sent out an inquiry to the Maven Dev mailing list musing about moving Maven’s official source repo to Git.

If you have yet to explore or fully leverage the power of Git or Maven, now is a critical juncture of market acceptance for these tools, and accordingly, a perfect time to explore their benefits. For the latest news on Git, Maven, iPhone development, and Open Source, join the conversation over at Twitter.

Maven 3.0 Early Access

Sunday, April 19th, 2009

Maven 3.0, a mostly-backwards compatible, but significantly improved and extensible version of Maven is developing very quickly. Jason van Zyl hosted a Maven Meetup at their offices in Mountain View in March of this year. Lots of deep information about Maven 2.0 and 3.0 was shared, and videos of some of the sessions are now starting to be posted to the Vimeo web site. The Maven 3.0 video is especially insightful:



Jason van Zyl on Maven 3 from Sonatype on Vimeo.

Here are the takeaway points, highly distilled to 140 proof, for those without time to watch the video:

  • Improved overarching performance (tools, engine, resolution, downloads, builds)
  • Better tooling integration
  • Tie-ins with OSGi
  • Excellence in Eclipse integration
  • Possibility of non-XML POMs
  • Lifecycle extension points
  • High-performance artifact resolution engine
  • Documentation-hyperlinked error messages

If you want to get access to the Maven 3.0 code, you can view the list of SVN checkout URLs here (or here for the hardcore Git lovers), or just view the source in your browser here. If you want early access to the binaries, you can download them from Apache.

iPhone Reaches 50% of Google’s Mobile Traffic

Wednesday, April 1st, 2009

If you need one more reason why, as a developer, you should learn Objective-C, here it is: The latest stats say that the iPhone is now 50% of Google’s mobile browser traffic. That is a crushing domination of the market share of even its nearest competitor, Symbian, with about 35%. Go grab a digital copy of Bill Dudney’s book, iPhone SDK Development, and then read it on your iPhone with the free Stanza .mobi reader. Then, hop on a plane and meet me at #NFJS Seattle this weekend for a talk on iPhone and Java Web Services.

Git More

Tuesday, March 24th, 2009

It seems like all the cool kids were already talking about Git, and now even the button-down organizations I work with are taking notice.

  1. JRuby is moving over to Kenai on a Git repository
  2. Grails is on GitHub. Yes, Graeme’s even excited about it. And Jason Rudolph is thinking he can nearly expunge his knowledge of git-svn.
  3. And my favorite Peanut butter and Chocolate story of Maven, Git and Ruby Gems is on a GitHub repo.

The folks in Minneapolis at NFJS and at the Albuquerque JUG last week had a rocking good time with Git when I presented it at both places.

Jason van Zyl of Maven fame has caught the Git bug too. And Don Brown and I work on the Maven CLI plugin in a GitHub repo, for which forking and pulling has become a way of life.

Part of this surge on Git is spurred by the fact that great new training materials are sprouting right and left. If you are hungry for more Git education, then in addition to the git bookmarks I’m constantly updating, take a look specifically at:

  1. The OGRE Git Tutorial
  2. The higher-education Git Magic eBook at Stanford
  3. The down to earth GitHub learning pages
  4. Or the brand new GitGuru

Git Going… and I’ll see you in Seattle in a little under two weeks to convince you Why Git is Better than X!