<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Kohsuke Kawaguchi&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/" />
<modified>2008-05-13T06:17:59Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2008, kohsuke</copyright>
<entry>
<title>My JavaOne highlights</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/05/my_javaone_high.html" />
<modified>2008-05-13T06:17:59Z</modified>
<issued>2008-05-13T06:17:59Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9789</id>
<created>2008-05-13T06:17:59Z</created>
<summary type="text/plain">My JavaOne 2008 wrap up</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[My JavaOne highlights

<dl>
<dt>Shook hands with Jonathan Schwartz</dt>
<dd>Jonathan Schwartz and Rich Green came to the GlassFish overview session in CommunityOne, of which I was a small part. I've seen Jonathan a few times in the cafeteria, but never so closely. I thought he got a little chubbier, but maybe it's just me. Their Q&amp;A time forced us to cut my part entirely :-(, but oh well.

<dt>People liked embeddable GlassFish</dt>
<dd>GlassFish had a good presence throughout the conference, and people liked its embeddability, too. Enabling more unit testing opporunities seem like one of the things people are interested in. We should push this further.

<dt><a href="http://www.cs.umd.edu/~pugh/">Bill Pugh</a> seems to like Hudson now
<dd>
Bill Pugh AKA Mr.FindBugs came to my Hudson booth, and we discussed about several things. Back when he visited Sun (maybe a year ago?) I showed him Hudson, and he appeared to be more knowledgable about Hudson now. He told me he'll mention Hudson in his "findbugs in anger" talk, and sure enough, after that, I started to see more people dropping by my booth, mentioning things like "hey, I just learned about Hudson in this conference ..."

<dt>Duke's Choice Award
<dd>
<a href="http://weblogs.java.net/blog/kohsuke/archive/2008/05/hudson_won_a_du.html">I already talked about this</a>. This year, the award ceremony wasn't a part of the James Gosling general session, and instead it was done in Tuesday evening. Unfortunately, I couldn't attend this ceremony because of a schedule conflict with the GlassFish v3 talk that Jerome and I gave.

<dt>JavaPosse came by
<dd>
JavaPosse was interviewing on the pavilion floor, and I got interviewed. I told them that <a href="http://weblogs.java.net/blog/kohsuke/archive/2008/04/i_think_my_daug.html">my daughter is a big fan of the opening Java-Java-jing-jing-jing song</a>. It looks like the interview became a part of <a href="http://www.javaposse.com/index.php?post_id=337675">episode 186</a>.

<dt>Tom Huybrechts came by
<dd>
He is one of the active Hudson committers, and this was the first time I met him in person. He had a very interesting plugin that he's working on, which uses JBoss BPEL engine and allow people to automate a complex work flow that can involve humans (think of a release process, for example.) He showed me how to design a workflow in Eclipse and uploads that to Hudson. I believe this will be his <a href="http://wiki.glassfish.java.net/Wiki.jsp?page=GapTop">GlassFish Award Program</a> submission. Can't wait to see it released.

<dt>Hudson session on Friday
<dd>
During the rehearsals, Rama and I were doing this constantly at about 50 minutes, but somehow in the real run, it took longer, and I had to rush things through toward the end. But otherwise I hope the presentation went all right (judging from a few blog postings like <a href="http://blogs.sun.com/plamere/entry/javaone_take_home_1_hudson">this</a> and e-mails, at least it impressed a few folks.) A part of the demo in which Rama showed the Maven integration where the user needed almost no configuration got an applause.

<dt>Hudson booth
<dd>
Every Duke's choice award winner gets a small booth, and thanks to this, in the first time in JavaOne, I was able to get my own booth. Jesse helped me man the booth. I liked this arrangement a lot, because now all I needed to do was to sit and wait for people to come see us. While I was able to talk to a lot of Hudson users, I also talked to many people who had no idea what Hudson was. I felt I needed more marketing.

<dt>Meet up with other Japanese developers in <a href="http://anfamily.com/portalpage.html">Thanh Long</a>
<dd>
This is a meet up for  people of what I call as "Maruyama-sensei school" &mdash; they are some of the best and the brightest Japanese developers, and I have an honor to be a small part of it. This yearly dinner became an integral part of JavaOne for me, and I meet new people every year. The food was expensive but good, and it was fun and inspiring. I run out of my business cards, which is a real shame because this is probably the only time I have any use for my business cards.

<dt>JetBrains developers knew me!
<dd>I went to the JetBrains booth to ask a few questions about TeamCity, but ended up talking more about IntelliJ IDEA, because some of them knew that I did a few plugins. What an honor. I got a few ideas about how to go about plugins that I wanted to write, so that was good. The person who did the Metro support in IDEA was there.

<dt>I stayed in San Francisco for a few nights
<dd>This year, I was able to stay in San Francisco for two nights, and it really made things convenient. I was able to be in a diner until midnight talking to folks, and yet next morning I was at the general session on time. Such an act is just impossible if I had to drive back and forth everyday from San Jose. It also allows me drink, which is another integral part of JavaOne :-) 
<br>
Speaking of drinking, I was counting on one free bear by <a href="http://weblogs.java.net/blog/fabriziogiudici/archive/2008/05/the_saddest_day.html">Fabrizio Giudici</a>, but I couldn't find him. Darn!

</dl>

<p>
On Saturday I opened <a href="http://www.amazon.com/LEGO-4498931-Creator-House/dp/B000JXQQ24">a lego creator house set</a>, which I bought for myself and saved it until after JavaOne, and played it a whole day with my daughter (lesson to myself &mdash; next year, buy two sets to avoid conflict!) Lego creator series is a lot more playable than some other series like Star Wars series.

<p>
On Sunday I took the family to <a href="http://www.niles.org/">Niles California</a> for antique shopping which my wife loves. I noticed that JavaOne is after Mother's day next year, which is probably not a good thing for our wives.

<p>
I still need to wrap up the last installment of <a href="http://gihyo.jp/dev/feature/01/hudson">my 5-part Hudson introduction article in Japanese</a>, but hopefully after that, I'd be able to come back to the regular life. Sorry for those who have reported issues for Hudson that I'm not attending them in a timely fashion, but please give me one more week.


]]>

</content>
</entry>
<entry>
<title>Hudson won a Duke&apos;s Choice Award</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/05/hudson_won_a_du.html" />
<modified>2008-05-12T18:22:41Z</modified>
<issued>2008-05-06T21:14:50Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9709</id>
<created>2008-05-06T21:14:50Z</created>
<summary type="text/plain">Hudson won Duke&apos;s Choice Award this year in JavaOne</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
This year in JavaOne, Hudson won Duke's Choice Award. Thank you very much for everyone for contributing/using Hudson!


<div align=center>
<img src="http://java.sun.com/javaone/images/dukes_choice_logo_08.gif">
</div>

<p>
P.S. <a href="http://www.cs.umd.edu/~pugh/">Bill Pugh</a> of findbugs dropped by the Hudson booth and told me that his Thursday talk "Using FindBugs in Anger" mentions Hudson. Nice!]]>

</content>
</entry>
<entry>
<title>Hudson booth at JavaOne</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/05/hudson_booth_at.html" />
<modified>2008-05-06T02:06:30Z</modified>
<issued>2008-05-06T02:06:14Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9693</id>
<created>2008-05-06T02:06:14Z</created>
<summary type="text/plain">If you are coming to JavaOne, don&apos;t forget to drop by at Hudson&apos;s booth inside Java Playground.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Communications</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
This year, we got a small comfy booth dedicated just for Hudson, inside a section called Java playground (and I just finished setting up a booth.)

<p>
So if you are coming to JavaOne, please consider dropping by. I might not be at the booth all the time, but looking forward to seeing many of you.]]>

</content>
</entry>
<entry>
<title>Embeddable GlassFish v3 in Grails</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/05/embeddable_glas.html" />
<modified>2008-05-02T15:49:23Z</modified>
<issued>2008-05-02T15:49:15Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9660</id>
<created>2008-05-02T15:49:15Z</created>
<summary type="text/plain">As another proof of concept for the embeddable GlassFish v3 that I discussed a few days ago, Vivek and I wrote a little addition to Grails so that you can use GlassFish v3 to run your Grails application.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Enterprise</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
As another proof of concept for <a href="http://weblogs.java.net/blog/kohsuke/archive/2008/04/glassfish_v3_ju.html">the embeddable GlassFish v3</a> that I discussed a few days ago, <a href="http://weblogs.java.net/blog/vivekp/">Vivek</a> and I wrote a little addition to <a href="http://grails.codehaus.org/">Grails</a> so that you can use GlassFish v3 instead of Jetty (As Vivek noted, I was quite happy with the ease of integration.)

<p>
<a href="http://weblogs.java.net/blog/vivekp/archive/2008/05/embedding_glass.html">Vivek's posting</a> has more details about internal working, but here's how you can use it:

<ol>
<li>Pick up the latest <tt>*-overlay.zip</tt> from <a href="http://maven.dyndns.org/2/org/glassfish/scripting/grails-gfv3/">here</a>. Extract this on top of your grails installation. I tested with 1.0.2.

<li>Whereas you normally run <tt>grails run-app</tt>, you can run <tt>grails run-app-gf</tt>
</ol>

<p>
The bundle currently contains the full-blown GlassFish v3, so it's bigger than it should be. But thanks to Maven, it should be easy to come up with a smaller bundle.

<p>
But in the mean time, there are several obvious benefits. This will bring you the full-brown JavaEE capabilities to your Grails app (such as JMS, web services, etc., although those are not yet in the technology preview 2.) Developers can now also run the application on the same container that they'll use in the production system, too.]]>

</content>
</entry>
<entry>
<title>Hudson community updates</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/05/hudson_communit.html" />
<modified>2008-05-01T19:20:49Z</modified>
<issued>2008-05-01T19:20:33Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9655</id>
<created>2008-05-01T19:20:33Z</created>
<summary type="text/plain">Some of the recent developments in Hudson: SCM plugins, Google Desktop, NetBeans, Japanese community, and JavaOne session.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
Some of the recent developments in Hudson:

<h3>More SCM plugins</h3>
<p>
It's amazing how many SCMs the world has developed, and it's even more amazing to see so many people signing up to write SCM plugins for Hudson. Michael Donohue recently added <a href="http://hudson.gotdns.com/wiki/display/HUDSON/BitKeeper+Plugin">BitKeeper plugin</a> and <a href="http://hudson.gotdns.com/wiki/display/HUDSON/URL+SCM">URL SCM plugin</a> (which is to check the timestamp of URL and if it's new it copies it over.) In the mean time, Nigel Magnay wrote a <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Git+Plugin">Git plugin</a> and <a href="http://blogs.sun.com/jglick/">Jesse</a> started hacking the Mercurial plugin more and more lately.

<h3>Google Gadget</h3>
<p>
Jeff Black wrote a <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Hudson+Google+Desktop+Gadget">Google Desktop gadest for Hudson</a>, which lets you see the status of builds in your desktop. This is neat, and the same idea should be useful for other gadget technologies.

<div align=center>
<img src=http://hudson.gotdns.com/wiki/download/attachments/20414483/screenshot_large-full.jpg>
</div>


<h3>NetBeans</h3>
<p>
The auther of Hudson NetBeans plugin have moved on to the film industry (seriously), so I talked to him and moved the plugin code to <a href="https://hudson.dev.java.net/source/browse/hudson/trunk/hudson/tools/ide/netbeans/">Hudson Subversion repository</a>. Jesse almost immediately started hacking, which is great.

<p>
Speaking of NetBeans, I was impressed with <a href="http://mevenide.codehaus.org/m2-site/">the latest Maven2 support in NetBeans 6.1</a> (the project team kindly sent me the latest bits for an experiment &mdash; I suspect this new version will be available for JavaOne.) For example, it lets you create a Hudson plugin from the new project wizard (through archetype), and it now also understands the repository index file from <a href="http://nexus.sonatype.org/">Nexus</a>, so I don't have to manually find out the exact groupId/artifactId any more.

<h3>Hudson and Japanese community</h3>
<p>
Hudson is growing among Japanese, too. (I think it helped that I started <a href="http://d.hatena.ne.jp/kkawa/">blogging in Japanese</a> as well.)  Kenji Nakamura has expanded the maven2 job type so that a bunch of plugins like port allocator or Xvnc can be used with it. I also just saw a Mantis plugin contribution from Seiji Sogabe.

<p>
There'a distribution of Trac in Japan called <a href="http://sourceforge.jp/projects/traclight/wiki/FrontPage">"Trac Lightening"</a> (which is very popular there due to its ease of installation and out-of-box experience), and this is switching to Hudson from Continuum.

<p>
The open source community in Japan is actually pretty strong, even though it might not be visible from here.


<div style="float:right">
  <img src="http://weblogs.java.net/blog/kohsuke/archive/20080428/170x93_Speaker_v4.gif">
</div>
<h3>Hudson at JavaOne</h3>
<p>
Rama and I will be doing a technical session on Hudson Friday noon (<a href="http://www28.cplan.com/sb191/session_details.jsp?isid=296547&ilocation_id=191-1&ilanguage=english">TS-6547 "Improving the Engineering Process Through Automation by Hudson"</a>.) The talk includes overview of Hudson, two demos, discussion of best practices for bigger Hudson deployments, and <a href="http://weblogs.java.net/blog/kohsuke/archive/2006/11/diyorb_my_own_e.html">the orb</a>. So don't forget to add that to your schedule.

<p>
Looking forward to seeing you all in JavaOne.]]>

</content>
</entry>
<entry>
<title>GlassFish v3 just got embeddable</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/04/glassfish_v3_ju.html" />
<modified>2008-04-28T22:34:12Z</modified>
<issued>2008-04-28T22:34:02Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9623</id>
<created>2008-04-28T22:34:02Z</created>
<summary type="text/plain">Now you can embed GlassFish v3 in any existing JVM and run it from there. This enables a whole range of possibilities.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Enterprise</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[

<h3>Embeddable GFv3</h3>
<p>
I've always liked Jetty's ability to run inside an existing JVM, just as a library of another application. This enabled Jetty to be used in many situations, like <tt>mvn jetty:run</tt> for
debugging a webapp without even running an application server on its own. IMO this contributed
to a part of Jetty's usefulness. Almost every Maven documents today use Jetty for
web app development, or doing <tt>site:run</tt>, etc.

<p>
So naturally, we wanted to do the same for GlassFish v3, and I'm happy to report that
it got to the point that it holds the water. I mean, I can now run <a href="https://hudson.dev.java.net/">Hudson</a> in this embedded GFv3.


<p>
Here's how it works &mdash; GlassFish v3 can be run as an OSGi appliation as <a href="http://weblogs.java.net/blog/ss141213/">Sahoo reported earlier</a>, but in fact it can also be run without any kind of classloader isolation system at all. Sure, you won't get the isolations, but this means you can just drop a bunch of GFv3 jars in your classpath and run it like that.

<p>
So I added a little bit of API around that to make things pretty, and now you have the embeddable GFv3 API, which can be used like this:

<pre style="margin-left:3em; border:1px solid black; padding:0.5em">
GlassFish glassfish = new GlassFish();
// create smallest possible HTTP set up listening on port 8080
glassfish.minimallyConfigure(8080);

GFApplication app = glassfish.deploy(new File("path/to/simple.war"));

...

app.undeploy();
glassfish.stop();
</pre>

<h3>Imagine the possibilities...</h3>
<p>
Thanks to the extensibility of GFv3, when you embed GFv3 in your JVM, you can plug into any of its extensibility points and tweak the behaviors in ways that you can't do with externally launched GFv3. You could also pick any flavor of GFv3 you want; if you just need the barebone servlet container and get smaller footprint, you can do that. But if you also need EJB functionality or some of our scripting offerings, that's cool with us, too. This is where we have an edge over Jetty, I think.

<p>
This is still a work in progress, but just imagine what we can do with this kind of stuff. How about testing your web services end-to-end without ever requring your developers to install GlassFish and set up database and all that. It also gives you interesting deployment options.

<p>
Oh, did I mention the start up time? One good thing about using a single classloader to load everything is that classloading overhead becomes much smaller. On my system, the server now starts in 300ms or so, complete with a deployment of a webapp. How many seconds does it take for your application server to start?



<h3>Maven-glassfish-plugin</h3>
<p>
I also wrote <a href="https://maven-glassfish-plugin.dev.java.net/">Maven glassfish plugin</a> to wrap this as a Maven plugin. This allows you to do <tt>mvn glassfish:run</tt> to run the web appliation that you are developing on Maven (the equivalent of <tt>mvn jetty:run</tt>.)

<p>
I'm also thinking about quickly putting together Ant tasks.


<h3>Conclusions</h3>
<div style="float:right; margin-left: 2em;">
<img alt="170x93_Speaker_v4.gif" src="http://weblogs.java.net/blog/kohsuke/archive/20080428/170x93_Speaker_v4.gif" width="170" height="93" />
</div>
<p>
As I wrote, this is still a work in progress, but please tell us what you think about where we are going.

<p>
Finally, I'll be co-speaking more about this in the upcoming JavaOne technical session <a href="http://www28.cplan.com/sb191/session_details.jsp?isid=295921&ilocation_id=191-1&ilanguage=english">"TS-5921 GlassFish Project v3 as an Extensible Server Platform."</a> If you are coming to JavaOne, I hope you'll come to the session.]]>

</content>
</entry>
<entry>
<title>Hudson plugin for WAR/EAR deployment / Cargo support in GlassFish</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/04/hudson_plugin_f.html" />
<modified>2008-04-24T03:15:32Z</modified>
<issued>2008-04-24T00:08:40Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9597</id>
<created>2008-04-24T00:08:40Z</created>
<summary type="text/plain">A new plugin Hudson to deploy a war to app servers, and a call for help for GlassFish support in Cargo.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Enterprise</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
I recently wrote <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Deploy+Plugin">a plugin for Hudson that deploys a WAR/EAR to the appliation container</a>. The typical intended use of this is that when you build a WAR on Hudson, you'd like to deploy it before commencing certain kind of testing.

<p>
I wanted this to be able to work with as many containers as possible, so I turned to <a href="http://cargo.codehaus.org/">Cargo</a> for abstracting away the difference in how you carry out a deployment. This is a very useful project indeed, and one of a kind (I wish APIs like this were a part of some relevant JavaEE JSRs, but oh well.)

<p>
Anyway, I've contributed embedded Tomcat support in the past to Cargo, so I knew the project rather well (and BTW that would be great for anyone who wants to run tests, as embedding a servlet container enables you to capture all the output in one place, instead of splitting this between the server and the client &mdash; debugging will be a lot easier, too.)

<p>
When I initially did the Tomcat work, I also wanted to do the GlassFish support. Unfortunately, after I did a partial work (you can check out the code by "svn co <a href="http://svn.codehaus.org/cargo-contrib/glassfish">http://svn.codehaus.org/cargo-contrib/glassfish</a>"), I had to move on to do other things, and I was never able to come back.

<p>
And now I really want this feature, and there's some partial code in there. Would there be anyone interested in picking up the work and bring it to the completion? I'm a Cargo committer, so I think I should be able to sponsor the integration into the main Cargo source tree. And more importantly, the Cargo team seems to be interested in getting this feature. It's just that the current code has the following problems:

<ol>
<li>It needs to satisfy the strict checkstyle rules of the Cargo project. They are very picky about whether a whitespace goes between 'if' and '(', whether '{' is on a new line, and so on.
<li>Integrate Cargo test cases to include GlassFish, which AIU is a requirement for code in the main Cargo source tree.
</ol>

<p>
The optional bonus credit would be to support the remote container mode of Cargo. I'm sure it's not too hard to do that.

<p>
This could be an excellent candidate for <a href="http://wiki.glassfish.java.net/Wiki.jsp?page=GapTop">the GlassFish Award Program</a>. See more about this issue in JIRA at <a href="http://jira.codehaus.org/browse/CARGO-491">CARGO-491</a>.
]]>

</content>
</entry>
<entry>
<title>I think my daughter is on the right track...</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/04/i_think_my_daug.html" />
<modified>2008-04-14T05:31:30Z</modified>
<issued>2008-04-14T05:31:23Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9526</id>
<created>2008-04-14T05:31:23Z</created>
<summary type="text/plain">I have a daughter who just became turned three, and she&apos;s already quite into Java!</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java User Groups</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
She just turned three, and she ...

<ol>
  <li>recognizes the Java logo and say "Java!!"
  <li>recognizes Duke and say "luke!!"
  <li>recognizes <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Logo">Hudson logo</a> and say "Hudson!!"
  <li>likes singing <a href="http://www.modlost.net/home/music/programming/java-song.html">the "Java java jing-jing-jing" song</a>, although the only part she can really sing is the endless repeat of "java java jing-jing-jing."
</ol>

<p>
Hmm... where did I make a mistake?]]>

</content>
</entry>
<entry>
<title>Hudson&apos;s SCM is just converted from CVS to Subversion</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/04/hudsons_scm_is.html" />
<modified>2008-04-07T18:52:27Z</modified>
<issued>2008-04-07T18:52:19Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9490</id>
<created>2008-04-07T18:52:19Z</created>
<summary type="text/plain">The source code repository of Hudson has been migrated from CVS to Subversion yesterday.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
When I first created  <a href="https://hudson.dev.java.net/">Hudson</a> on java.net, java.net only had CVS and no Subversion. Since then, java.net had added the Subversion support so that new projects can choose to use Subversion, but the existing projects didn't really have any viable migration path.

<p>
Some time after that, this got the attention of the java.net team, and <a href="http://wiki.java.net/bin/view/Javanet/UserGeneratedFAQs#CVStoSVN">a document has been written to explain how to migrate</a>. Unfortunately, the catch is that you have to pay a fee to do this, and I couldn't convince myself to pay $500 (or so) myself to do this, so I left it there.

<p>
As Subversion steadily replaces CVS everywhere, however, it was just a matter of time before this issue gets revisited, and that happened a couple of weeks back. Tom Huybrechts <a href="http://www.nabble.com/hudson-on-subversion-tt16261374.html">brought this up again</a>, and I replied that "yes, we tried, and we need to do some fund raising to do this." That was when a little miracle happened. See, collab.net is now apparently using Hudson, and one of their developers, Adam Ambrose, was in the Hudson dev list. <a href="http://www.nabble.com/-IMPORTANT--CVS-%3ESubversion-conversion-tt16408894.html#a16409736">He kindly talked about this inside Collab.net</a>, and as a result, they graciously agreed to do the conversion for free for us. How nice of them!

<p>
So this morning, I was happy to find a new Subversion repository for Hudson. I still have to make adjustments to release scripts, but documents on Wiki are already updated to reflect this change. For those of you who have Hudson source code checked out, see this document for <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Building+Hudson">how to do it now</a>, ]]>

</content>
</entry>
<entry>
<title>I&apos;m a rock star programmer!</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/04/im_a_rock_star.html" />
<modified>2008-04-07T17:10:10Z</modified>
<issued>2008-04-07T17:10:00Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9489</id>
<created>2008-04-07T17:10:00Z</created>
<summary type="text/plain">First, apologies for a shameless plug. Ed Burns interviewed me and that interview became a part of his book &quot;Secrets of the Rock Star Programmers: Riding the IT Crest.&quot;</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<div style="float:right">
<a href="http://www.amazon.com/gp/product/0071490833?ie=UTF8&tag=kohsukawagswe-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0071490833"><img alt="cover.jpg" src="http://weblogs.java.net/blog/kohsuke/archive/20080407/cover.jpg" width="129" height="160" /></a><img src="http://www.assoc-amazon.com/e/ir?t=kohsukawagswe-20&l=as2&o=1&a=0071490833" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
</div>

<p>
First, apologies for a shameless plug. <a href="http://weblogs.java.net/blog/edburns/">Ed Burns</a> interviewed me when we were at Sun's internal conference (this was a rather nice place near Santa Cruz), and that interview became a part of his book <a href="http://www.amazon.com/gp/product/0071490833?ie=UTF8&tag=kohsukawagswe-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0071490833">"Secrets of the Rock Star Programmers: Riding the IT Crest."</a> We talked about many different things, but I enjoyed the process. What's interesting is that sometimes I learn myself by what I'm saying to others, and this was no exception.

<p>
He just gave me a copy when I met him at the server-side Java symposium, so I haven't read the whole thing yet, but I find the book enjoyable, partly because I recognize many names in the book as they are mainly from the Java community.]]>

</content>
</entry>
<entry>
<title>I resurrected my Japanese blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/04/i_resurrected_m.html" />
<modified>2008-04-05T01:57:59Z</modified>
<issued>2008-04-05T01:57:52Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9477</id>
<created>2008-04-05T01:57:52Z</created>
<summary type="text/plain">As Hudson improves its presence in Japan, I decided to resurrect my old blog in Japanese that I haven&apos;t touched for a long time.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
As Hudson improves its presence in Japan, I decided to <a href="http://d.hatena.ne.jp/kkawa/">resurrect my old blog in Japanese that I haven't touched for a long time</a>.

<p>
Many of the postings are the translation of the posts I made here, but there are some additional posts in there as replies to the reactions that my posting caused among Japanese bloggers.]]>

</content>
</entry>
<entry>
<title>Deep dive into assembly code from Java</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/03/deep_dive_into.html" />
<modified>2008-03-31T06:10:26Z</modified>
<issued>2008-03-31T06:10:18Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9446</id>
<created>2008-03-31T06:10:18Z</created>
<summary type="text/plain">One of the things I learned in The Server Side Java Symposium 2008 was a command-line option to print out the assembly code that JIT is producing. Since I&apos;ve always been interested in seeing the final assembly code that gets produced from your Java code, I decided to give it a test drive.
</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
One of the things I learned in <a href="http://javasymposium.techtarget.com/index.html">The Server Side Java Symposium 2008</a> was a command-line option to print out the assembly code that JIT is producing. Since I've always been interested in seeing the final assembly code that gets produced from your Java code, I decided to give it a test drive.

<p>
First the disclaimers:

<blockquote style="font-weight:bold; color:darkred">
<ol>
<li>I'm not a performance expert.
<li>Don't try to take this too far, like optimizing your code against what you see here.
</blockquote>

<p>
The option in question is only available in debug builds of JDKs. You can download one from <a href="http://download.java.net/jdk6/binaries/">here</a>. The binary I tested is JDK6 u10 b14.

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em">
$ java -fullversion
java full version "1.6.0_10-beta-fastdebug-b14"
</pre>

<p>
First, let's try something trivial:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>public class Main {
    public static void main(String[] args) {
        for(int i=0; i<100; i++)
            foo();
    }

    private static void foo() {
        for(int i=0; i<100; i++)
            bar();
    }

    private static void bar() {
    }
}</xmp></pre>

<p>
I run this like "<tt>java -XX:+PrintOptoAssembly -server -cp . Main</tt>". The <tt>-XX:+PrintOptoAssembly</tt> is the magic option, and with this option I get the following, which shows the code of the "foo" method:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>000   B1: #     N1 <- BLOCK HEAD IS JUNK   Freq: 100
000     pushq   rbp
        subq    rsp, #16        # Create frame
        nop     # nop for patch_verified_entry
006     addq    rsp, 16 # Destroy frame
        popq    rbp
        testl   rax, [rip + #offset_to_poll_page]       # Safepoint: poll for GC

011     ret</xmp></pre>

<p>
You see that the entire bar() function call and the loop was optimized away. So it must have inlined the bar() method, then unrolled the loop.

<p>
Now to something more interesting:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>    private static byte[] foo() {
        byte[] buf = new byte[256];
        for( int i=0; i<buf.length; i++ )
            buf[i] = 0;
        return buf;
    }</xmp></pre>

<p>
This produces the following code:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>000   B1: #     B15 B2 <- BLOCK HEAD IS JUNK   Freq: 78
000     # stack bang
        pushq   rbp
        subq    rsp, #80        # Create frame
00c     # TLS is in R15
00c     movq    R8, [R15 + #120 (8-bit)]        # ptr
010     movq    R10, R8 # spill
013     addq    R10, #280       # ptr
01a     cmpq    R10, [R15 + #136 (32-bit)]      # raw ptr
021     jge,u   B15  P=0.000100 C=-1.000000
021
027   B2: #     B3 <- B1  Freq: 77.9922
027     movq    [R15 + #120 (8-bit)], R10       # ptr
02b     PREFETCHNTA [R10 + #256 (32-bit)]       # Prefetch to non-temporal cache for write
033     movq    [R8], 0x0000000000000001        # ptr
03a     PREFETCHNTA [R10 + #320 (32-bit)]       # Prefetch to non-temporal cache for write
042     movq    RDI, R8 # spill
045     addq    RDI, #24        # ptr
049     PREFETCHNTA [R10 + #384 (32-bit)]       # Prefetch to non-temporal cache for write
051     movl    RCX, #32        # long (unsigned 32-bit)
056     movq    R10, precise klass [B: 0x00002aaaab076708:Constant:exact *      # ptr
060     movq    [R8 + #8 (8-bit)], R10  # ptr
064     movl    [R8 + #16 (8-bit)], #256        # int
06c     xorl    rax, rax        # ClearArray:
        rep stosq       # Store rax to *rdi++ while rcx--
071
071   B3: #     B4 <- B16 B2  Freq: 78
071   
071     # checkcastPP of R8
071     xorl    R10, R10        # int
074     movl    R9, #256        # int
        nop     # 2 bytes pad for loops and calls

07c   B4: #     B17 B5 <- B3 B5         Loop: B4-B5 inner stride: not constant pre of N153 Freq: 19850.2
07c     cmpl    R10, #256       # unsigned
083     jge,u   B17  P=0.000001 C=-1.000000
083
089   B5: #     B4 B6 <- B4  Freq: 19850.2
089     movslq  R11, R10        # i2l
08c     movb    [R8 + #24 + R11], #0    # byte
092     incl    R10     # int
095     cmpl    R10, #8
099     jlt,s   B4  P=0.996072 C=22313.000000
099
09b   B6: #     B11 B7 <- B5  Freq: 77.9799
09b     subl    R9, R10 # int
09e     andl    R9, #-16        # int
0a2     addl    R9, R10 # int
0a5     cmpl    R10, R9
0a8     jge,s   B11  P=0.500000 C=-1.000000
0a8
0aa   B7: #     B8 <- B6  Freq: 38.9899
0aa     PXOR  XMM0,XMM0 ! replicate8B
        nop     # 2 bytes pad for loops and calls

0b0   B8: #     B10 B9 <- B7 B9         Loop: B8-B9 inner stride: not constant main of N85 Freq: 9925.09
0b0     movslq  R11, R10        # i2l
0b3     MOVQ  [R8 + #24 + R11],XMM0     ! packed8B
0ba     movl    R11, R10        # spill
0bd     addl    R11, #16        # int
0c1     movslq  R10, R10        # i2l
0c4     MOVQ  [R8 + #32 + R10],XMM0     ! packed8B
0cb     cmpl    R11, R9
0ce     jge,s   B10  P=0.003928 C=22313.000000
0ce
0d0   B9: #     B8 <- B8  Freq: 9886.1
0d0     movl    R10, R11        # spill
0d3     jmp,s   B8
0d3
0d5   B10: #    B11 <- B8  Freq: 38.9899
0d5     movl    R10, R11        # spill
0d5
0d8   B11: #    B14 B12 <- B6 B10  Freq: 77.9799
0d8     cmpl    R10, #256
0df     jge,s   B14  P=0.500000 C=-1.000000
        nop     # 3 bytes pad for loops and calls

0e4   B12: #    B17 B13 <- B11 B13      Loop: B12-B13 inner stride: not constant post of N153 Freq: 9922.54
0e4     cmpl    R10, #256       # unsigned
0eb     jge,us  B17  P=0.000001 C=-1.000000
0eb
0ed   B13: #    B12 B14 <- B12  Freq: 9922.53
0ed     movslq  R11, R10        # i2l
0f0     movb    [R8 + #24 + R11], #0    # byte
0f6     incl    R10     # int
0f9     cmpl    R10, #256
100     jlt,s   B12  P=0.996072 C=22313.000000
100
102   B14: #    N1 <- B13 B11  Freq: 77.9698
102     movq    RAX, R8 # spill
105     addq    rsp, 80 # Destroy frame
        popq    rbp
        testl   rax, [rip + #offset_to_poll_page]       # Safepoint: poll for GC

110     ret
110
111   B15: #    B18 B16 <- B1  Freq: 0.00780129
111     movq    RSI, precise klass [B: 0x00002aaaab076708:Constant:exact *      # ptr
11b     movl    RDX, #256       # int
120     nop     # 3 bytes pad for loops and calls
123     call,static  wrapper for: _new_array_Java
        # Main::foo @ bci:3  L[0]=_ L[1]=_
        # 
128
128   B16: #    B3 <- B15  Freq: 0.00780114
        # Block is sole successor of call
128     movq    R8, RAX # spill
12b     jmp     B3
12b
130   B17: #    N1 <- B12 B4  Freq: 1e-06
130     movl    RSI, #-28       # int
135     movq    RBP, R8 # spill
138     movl    [rsp + #0], R10 # spill
13c     nop     # 3 bytes pad for loops and calls
13f     call,static  wrapper for: uncommon_trap(reason='range_check' action='make_not_entrant')
        # Main::foo @ bci:17  L[0]=RBP L[1]=rsp + #0 STK[0]=RBP STK[1]=rsp + #0 STK[2]=#0
        # AllocatedObj(0x0000000040c31880)

144     int3    # ShouldNotReachHere
144
151   B18: #    N1 <- B15  Freq: 7.80129e-08
151     # exception oop is in rax; no code emitted
151     movq    RSI, RAX        # spill
154     addq    rsp, 80 # Destroy frame
        popq    rbp

159     jmp     rethrow_stub</xmp></pre>

<p>
Just to recap, R8-R15 are additional general-purpose 64bit registers new in the <a href="http://en.wikipedia.org/wiki/X86-64">amd64</a>. 

<p>
The first part (00c-027) is allocating an array, and this is already interesting. As the comment indicates, <tt>R15</tt> is apparently used as a pointer to a thread-local storage of the current thread, and <tt>R15[120]</tt> is the pointer to the head of the heap sub-space dedicated for this thread.

<p>
So the <tt>byte[]</tt> is allocated from this thread-local space by simply reserving 256+32 byte space. If there's not enough space (the limit is set at <tt>R15[136]</tt>), then it uses the slower allocation code at <tt>B15</tt> &mdash; this code must involve in reserving a new chunk from the eden space and allocate a new object there.

<p>
Once the pointer to the new array is set to <tt>R8</tt> at <tt>00c</tt>, the initialization follows (<tt>033-071</tt>.) The first 24 bytes of the newly allocated space is used for metadata (the first 8 byte is probably lock or GC-related, followed by a pointer to the class object, then another 8 bytes for the size of the array.) <tt>06c</tt> zero-clears the array. In theory the zero-clear shouldn't have been necessary, as we are then filling the array to zero again, but JIT failed to take advantage of that.

<p>
But note that the zero-clear is done by 8 bytes at a time, so it did recognize that the array size is multiple of 8.

<p>
I don't quite understand what those prefetch instructions (at 02b, 03a, and 049) are meant for. Presumably they are to make sure that the next time an object allocation happens, that part of the memory is in cache, but why 256, 320, and 384? Does anyone have a clue?

<p>
Now as of 074, <tt>R8</tt> is the pointer to 'buf' and R9 is the length of the array. Note that JIT knows that <tt>buf.length</tt> is always 256 here, so this is <tt>movl R9,256</tt> and not <tt>movl R9,[R8+16]</tt>. Also note that this computation is outside the for loop. So this tells us that there's no need to explicitly assign the array length to a temporary variable in a tight loop, because JIT does the equivalent anyway:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>int len = buf.length;
for( int i=0; i<len; i++ )
  ...</xmp></pre>

<p>
Similarly there's no need to reverse the direction of the loop to avoid <tt>buf.length</tt> computation.

<p>
The way the loop is compiled is very interesting. First there's the 'warm up' part (07c-099) that presumably does the array filling until it reaches the 8-byte boundary, then the 'fast loop' portion (09b-0d3) that zero-fills 8 bytes per loop by using an MMX register, then the final 'cool down' part (0d5-100) that handles the last remaining part that doesn't fit 8 byte boundary. In this case, in theory it could have figured out that the whole thing nicely fits 8-byte boundary, so the warm up and cool down was unnecessary, but it appears that JIT didn't realize this.

<p>
I don't know what kind of computation happens behind the scene here, but overall this loop unrolling is rather clever. The original code was byte-by-byte assignment to 0, but in the final code, one loop iteration clears 8 byte at a time. 

<p>
I also noticed that there's no array boundary check in the fast loop portion, which is nice.


<p>
OK, most of you have hopefully heard that in JDK6 they do <a href="http://www.ibm.com/developerworks/java/library/j-jtp10185/index.html">lock coarsening and lock elision</a>. So let's see that in action.

<p>
For that, I compiled the following code and executed in the same fashion:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>    private static void foo() {
        Vector v = new Vector();
        v.add("abc");
        v.add("def");
        v.add("ghi");
    }</xmp></pre>

<p>
This gives me the following:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>000   B1: #     B10 B2 <- BLOCK HEAD IS JUNK   Freq: 20168
000     # stack bang
        pushq   rbp
        subq    rsp, #80        # Create frame
00c     # TLS is in R15
00c     movq    RAX, [R15 + #120 (8-bit)]       # ptr
010     movq    R10, RAX        # spill
013     addq    R10, #40        # ptr
017     # TLS is in R15
017     cmpq    R10, [R15 + #136 (32-bit)]      # raw ptr
01e     jge,u   B10  P=0.000100 C=-1.000000
01e
024   B2: #     B3 <- B1  Freq: 20166
024     # TLS is in R15
024     movq    [R15 + #120 (8-bit)], R10       # ptr
028     PREFETCHNTA [R10 + #256 (32-bit)]       # Prefetch to non-temporal cache for write
030     movq    R10, precise klass java/util/Vector: 0x00002aaaf2649f38:Constant:exact *        # ptr
03a     movq    R11, [R10 + #176 (32-bit)]      # ptr
041     movq    [RAX], R11      # ptr
044     movq    [RAX + #8 (8-bit)], R10 # ptr
048     movq    [RAX + #16 (8-bit)], #0 # long
050     movq    [RAX + #24 (8-bit)], #0 # long
058     movq    [RAX + #32 (8-bit)], #0 # long
058
060   B3: #     B12 B4 <- B11 B2  Freq: 20168
060     
060     movq    RBP, RAX        # spill
063     # checkcastPP of RBP
063     # TLS is in R15
063     movq    R11, [R15 + #120 (8-bit)]       # ptr
067     movq    R10, R11        # spill
06a     addq    R10, #104       # ptr
06e     # TLS is in R15
06e     cmpq    R10, [R15 + #136 (32-bit)]      # raw ptr
075     jge,u   B12  P=0.000100 C=-1.000000
075
07b   B4: #     B5 <- B3  Freq: 20166
07b     # TLS is in R15
07b     movq    [R15 + #120 (8-bit)], R10       # ptr
07f     PREFETCHNTA [R10 + #256 (32-bit)]       # Prefetch to non-temporal cache for write
087     movq    [R11], 0x0000000000000001       # ptr
08e     PREFETCHNTA [R10 + #320 (32-bit)]       # Prefetch to non-temporal cache for write
096     movq    RDI, R11        # spill
099     addq    RDI, #24        # ptr
09d     PREFETCHNTA [R10 + #384 (32-bit)]       # Prefetch to non-temporal cache for write
0a5     movq    R10, precise klass [Ljava/lang/Object;: 0x00002aaaf264e928:Constant:exact *     # ptr
0af     movq    [R11 + #8 (8-bit)], R10 # ptr
0b3     movl    [R11 + #16 (8-bit)], #10        # int
0bb     movl    RCX, #10        # long (unsigned 32-bit)
0c0     xorl    rax, rax        # ClearArray:
        rep stosq       # Store rax to *rdi++ while rcx--
0c5
0c5   B5: #     B16 B6 <- B13 B4  Freq: 20168
0c5     
0c5     # checkcastPP of R11
0c5     movq    [RBP + #32 (8-bit)], R11        # ptr ! Field java/util/Vector.elementData
0c9     movq    R10, RBP        # ptr -> long
0cc     shrq    R10, #9
0d0     movq    RDX, java/lang/String:exact *   # ptr
0da     movq    R11, 0x00002a959c9da580 # ptr
0e4     movb    [R11 + R10], #0 # byte
0e9     movq    RSI, RBP        # spill
0ec     nop     # 3 bytes pad for loops and calls
0ef     call,static  java.util.Vector::add
        # Main::foo @ bci:11  L[0]=RBP
        # AllocatedObj(0x0000000040b30680)

0f4
0f4   B6: #     B15 B7 <- B5  Freq: 20167.6
        # Block is sole successor of call
0f4     movq    RDX, java/lang/String:exact *   # ptr
0fe     movq    RSI, RBP        # spill
101     nop     # 2 bytes pad for loops and calls
103     call,static  java.util.Vector::add
        # Main::foo @ bci:18  L[0]=RBP
        # AllocatedObj(0x0000000040b30680)

108
108   B7: #     B14 B8 <- B6  Freq: 20167.2
        # Block is sole successor of call
108     movq    RDX, java/lang/String:exact *   # ptr
112     movq    RSI, RBP        # spill
115     nop     # 2 bytes pad for loops and calls
117     call,static  java.util.Vector::add
        # Main::foo @ bci:25  L[0]=_
        # 
11c
11c   B8: #     N1 <- B7  Freq: 20166.8
        # Block is sole successor of call
11c     addq    rsp, 80 # Destroy frame
        popq    rbp
        testl   rax, [rip + #offset_to_poll_page]       # Safepoint: poll for GC
        
127     ret

(slow path omitted)</xmp></pre>

<p>
The allocation of a <tt>Vector</tt> object (00c-058) is almost identical to the array allocation code we've seen before (except the additional field initializations at 048-058.) The array allocation for <tt>Vector.elementData</tt> follows (060-0C0.)

<p>
Note that the <tt>Vector</tt> constructors are defined in highly nested fashion like this:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>    public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

    public Vector() {
        this(10);
    }</xmp></pre>

<p>
... but the whole thing is inlined, so the end result is just as fast as the following code. This is great.

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>    public Vector() {
        this.elementData = new Object[10];
        this.capacityIncrement = 0;
    }</xmp></pre>

<p>
But wait, after that, you see that there's three <tt>call</tt> instructions for <tt>Vector.add</tt>. So there's no lock elision nor lock coarsening, despite the fact that this <tt>Vector</tt> object never escapes the stack.

<p>
I thought perhaps that's because <tt>Vector.add</tt> is too complex to be inlined, so I tried the following code, in the hope of seeing the lock elision:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>    private static void foo() {
        Foo foo = new Foo();
        foo.inc();
        foo.inc();
        foo.inc();
    }

    private static final class Foo {
        int i=0;

        public synchronized void inc() {
            i++;
        }
    }</xmp></pre>

This produced the following code:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>000   B1: #     B6 B2 <- BLOCK HEAD IS JUNK   Freq: 19972
000     # stack bang
        pushq   rbp
        subq    rsp, #80        # Create frame
00c     # TLS is in R15
00c     movq    RBP, [R15 + #120 (8-bit)]       # ptr
010     movq    R10, RBP        # spill
013     addq    R10, #24        # ptr
017     cmpq    R10, [R15 + #136 (32-bit)]      # raw ptr
01e     jge,u   B6  P=0.000100 C=-1.000000
01e
024   B2: #     B3 <- B1  Freq: 19970
024     movq    [R15 + #120 (8-bit)], R10       # ptr
028     PREFETCHNTA [R10 + #256 (32-bit)]       # Prefetch to non-temporal cache for write
030     movq    R10, precise klass Main$Foo: 0x00002aaaf2646e58:Constant:exact *        # ptr
03a     movq    R11, [R10 + #176 (32-bit)]      # ptr
041     movq    [RBP], R11      # ptr
045     movq    [RBP + #8 (8-bit)], R10 # ptr
049     movq    [RBP + #16 (8-bit)], #0 # long
049
051   B3: #     B8 B4 <- B7 B2  Freq: 19972
051     
051     # checkcastPP of RBP
051     leaq    R11, [rsp + #64]        # box lock
056     fastlock RBP,R11,RAX,R10
135     jne     B8  P=0.000001 C=-1.000000
135
13b   B4: #     B9 B5 <- B8 B3  Freq: 19972
13b     MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)
13b     movl    R11, [RBP + #16 (8-bit)]        # int ! Field Main$Foo.i
13f     incl    R11     # int
142     movl    [RBP + #16 (8-bit)], R11        # int ! Field Main$Foo.i
146     MEMBAR-release
146     MEMBAR-acquire
146     movl    R11, [RBP + #16 (8-bit)]        # int ! Field Main$Foo.i
14a     incl    R11     # int
14d     movl    [RBP + #16 (8-bit)], R11        # int ! Field Main$Foo.i
151     MEMBAR-release
151     MEMBAR-acquire
151     movl    R11, [RBP + #16 (8-bit)]        # int ! Field Main$Foo.i
155     incl    R11     # int
158     movl    [RBP + #16 (8-bit)], R11        # int ! Field Main$Foo.i
15c     MEMBAR-release (a FastUnlock follows so empty encoding)
15c     leaq    RAX, [rsp + #64]        # box lock
161     fastunlock RBP, RAX, R10
218     jne,s   B9  P=0.000001 C=-1.000000
218
21a   B5: #     N1 <- B9 B4  Freq: 19972
21a     addq    rsp, 80 # Destroy frame
        popq    rbp
        testl   rax, [rip + #offset_to_poll_page]       # Safepoint: poll for GC
        
225     ret

(slow path omitted)</xmp></pre>

<p>
We are all familar with the memory allocation by now, so we can skip that.

<p>
The 'fastlock' pseudo-instruction (AFAIK there's no such operation in amd64, and a single machine code can't possibly occupy 223 bytes!) must be the lock code. Here you see that the lock coarsening has indeed happened (yay!), and three increments happen in a single block (MEMBAR-acquire/release must be another pseudo-instruction, which became no-op in this scenario &mdash; see that the length of those instructions are 0).

<p>
Note that JVM still fails to eliminate a lock here, despite the fact that this object doesn't escape the stack. I tried various things to see the effect of escape analysis and lock elision kick in, but couldn't find a way to do it. <a href="http://blog.xebia.com/2007/12/21/did-escape-analysis-escape-from-java-6/">It looks like this feature is not quite in JDK yet</a>, although it's equally possible that I'm doing something stupid.

<p>
Also note that presumably because of the memory barrier associated with this, each increments write back to memory. This is unfortunate because in theory three increments could have been combined into one, given the the lock was coarsened.

<p>
Indeed if I remove the 'synchronized' keyword, I get the following substantially simpler version:

<pre style="margin-left:2em; border:1px solid black; background-color:#eee; padding: 0.5em"><xmp
>000   B1: #     B4 B2 <- BLOCK HEAD IS JUNK   Freq: 27066
000     # stack bang
        pushq   rbp
        subq    rsp, #16        # Create frame
00c     # TLS is in R15
00c     movq    RAX, [R15 + #120 (8-bit)]       # ptr
010     movq    R10, RAX        # spill
013     addq    R10, #24        # ptr
017     cmpq    R10, [R15 + #136 (32-bit)]      # raw ptr
01e     jge,us  B4  P=0.000100 C=-1.000000
01e
020   B2: #     B3 <- B1  Freq: 27063.3
020     movq    [R15 + #120 (8-bit)], R10       # ptr
024     PREFETCHNTA [R10 + #256 (32-bit)]       # Prefetch to non-temporal cache for write
02c     movq    R10, precise klass Main$Foo: 0x00002aaaf25dfbc8:Constant:exact *        # ptr
036     movq    R11, [R10 + #176 (32-bit)]      # ptr
03d     movq    [RAX], R11      # ptr
040     movq    [RAX + #8 (8-bit)], R10 # ptr
040
044   B3: #     N1 <- B5 B2  Freq: 27066
044     movq    [RAX + #16 (8-bit)], #3 # long
04c     
04c     addq    rsp, 16 # Destroy frame
        popq    rbp
        testl   rax, [rip + #offset_to_poll_page]       # Safepoint: poll for GC
        
057     ret

(slow path omitted)</xmp></pre>

<p>
So not only three <tt>inc()</tt>s but the initializer also got collapsed into single "movq rax[16],3" call. Wow!


<p>
All in all, modern JVMs seem pretty good at generating optimal code. In various situations, the resulting assembly code is far from the straight-forward instruction-by-instruction translation. OTOH, the escape analysis doesn't really seem to do anything useful yet.

<p>
This was a long post, but I hope you enjoyed this as much as I did.]]>

</content>
</entry>
<entry>
<title>Introducing java.net SCM/issue tracker cross-linking daemon</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/03/introducing_jav_1.html" />
<modified>2008-03-29T20:04:04Z</modified>
<issued>2008-03-29T20:02:11Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9440</id>
<created>2008-03-29T20:02:11Z</created>
<summary type="text/plain">I wrote a daemon that creates cross-linking between SCM and issue trackers by using keywords in commit messages.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
I've further updated <a href="https://javanettasks.dev.java.net/">the java.net tasks library</a> so that I can programatically interact with the java.net issue tracker, then build a new daemon on it.

<p>
This new daemon, <a href="https://scm-issue-link.dev.java.net/"><tt>scm-issue-link</tt></a>, monitors SCM commits. If commit messages contain references to issues, the daemon then updates those issues, creating back-links to the SCM commits. A similar feature can be seen in other issue trackers, like Trac or JIRA.

This makes it easier for developers to later go back the project history and determine what changes are made for a particular issue. With this daemon, this feature is finally available for any java.net projects.

<p>
To use this, first add the daemon user (<tt>scm_issue_link</tt>) as a developer on your project. This tells daemon that you'd like him to update issues in your project. The daemon has to periodically poll java.net to see what project he's invited on, so it will take up to an hour for this initial phase to complete.

<p>
Once the daemon is hooked, simply reference issues when you make commits. The daemon understands several syntaxes, like "issue #50" "Issue 100" or "HUDSON-123". Within a few minutes, the daemon will update issues with back references.

<p>
See <a href="https://hudson.dev.java.net/issues/show_bug.cgi?id=37">a sample issue</a> updated by this daemon, and if you have any suggestions/ideas about how the daemon can be improved, let me know. If you are interested in hacking the daemon, that is welcome, too!

]]>

</content>
</entry>
<entry>
<title>Kohsuke at The Server-Side Java Symposium</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/03/kohsuke_at_the.html" />
<modified>2008-03-26T07:04:06Z</modified>
<issued>2008-03-26T07:04:00Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9425</id>
<created>2008-03-26T07:04:00Z</created>
<summary type="text/plain">This week I&apos;m in Las Vegas to give a talk in TSSJS about how to build fast and scalable web services in Metro.</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[<p>
This week I'm in Las Vegas to give a talk in TSSJS about how to build fast and scalable web services in Metro. If you are also in town and interested in meeting up, let me know!

<p>
(or alternatively, you can just watch out for a guy in Hudson T-shirt...)]]>

</content>
</entry>
<entry>
<title>Hudson hits 1.200</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/kohsuke/archive/2008/03/hudson_hits_120.html" />
<modified>2008-03-24T18:45:16Z</modified>
<issued>2008-03-24T18:45:11Z</issued>
<id>tag:weblogs.java.net,2008:/blog/kohsuke/208.9410</id>
<created>2008-03-24T18:45:11Z</created>
<summary type="text/plain">Hudson finally hit 1.200 last Friday. It&apos;s not 1.2 nor 1.2.0.0 --- it&apos;s 1.200, the 201st release of Hudson since it&apos;s 1.0 release, which was a little over 3 years ago.
</summary>
<author>
<name>kohsuke</name>

<email>Kohsuke.Kawaguchi@Sun.COM</email>
</author>
<dc:subject>Community: Java Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/kohsuke/">
<![CDATA[Hudson finally hit 1.200 last Friday. It's not 1.2 nor 1.2.0.0 &mdash; it's 1.200, the 201st release of Hudson since it's 1.0 release, which was a little over 3 years ago.

<p>
A few weeks back when I knew that it's approaching 200 mark, I briefly thought about giving it a longer soak time to make it a very stable release,
or perhaps adding some major RFE in this release. Or even call it 2.0. But in the end I just kept doing what I've been doing all along, and next thing I knew it was already 1.200!

<p>
I'd like to take this opportunity to thank all the contributers and users for making Hudson better. Hudson came a long way, but it still got a long way to go, too. So I hope you guys will stick around.

<div align=center>
<img alt="Birthday_candles.jpg" src="http://weblogs.java.net/blog/kohsuke/archive/20080324/Birthday_candles.jpg" width="300" height="111" />
</div>
]]>

</content>
</entry>

</feed>