Tuesday, April 28, 2009

Lack of memory

1 comments
A very interesting thing happened a few days ago. After searching for a solution to an error message I was getting when running Apache Tomcat, I came across the following post:

https://issues.apache.org/bugzilla/show_bug.cgi?id=39090

And I found the solution to my problem in the comment #5. By accident, I saw the author of the comment and, to my surprise, I had been the author in 2006! Yes, that's right. I had absolutely no memory of writing this comment. And this solution is mentioned in many other places after I added this comment there.

Actually, I ended up using Tomcat 6 due to the nuisance of having to change a lot of stuff in my project at Amazon, but this finding was funny anyway.

Saturday, April 04, 2009

Cygwin: created files (e.g. tar) have shared icon on Windows Vista

0 comments
Everytime I create a file in cygwin shell, files end up with the shared folder icon on Windows Vista and it is a hell of pain to remove this icon (unsharing a folder takes a whole lot of time). This happens with files under your Documents folder, not with files created elsewhere.

In order to fix this behavior, you can do the following in a cygwin shell:

export CYGWIN=nontsec

Or even better, edit your .bashrc and add this export to be done everytime you launch a new shell.

Thursday, April 02, 2009

Hudson Plugin 2: Adding a Post-Build action (for a Reporter/Publisher)

1 comments
This is a follow-up to the Hudson Plugin 1. As told before, you create the plugin skeleton using:
mvn hpi:create
This creates a plugin skeleton through the maven-hpi-plugin. As of this writing, the latest version (1.34) generates a code that uses adeprecated way of doing so, and it is the skeleton of a Builder plugin.

Since we are building a Recorder/Publisher and we will use the recommended way of defining a plugin (through the Extension annotation), we will have to change most of the code. But it is important to understand what is the structure, so that's the value of generating the skeleton. Specially because of Hudson's choice of using Jelly for the plugin portions of the HTML page.
  • src/main/java
    plugin Java code
  • src/main/resource
    jelly files where you specify code for the configuration of plugin (global and project configuration).


Java Code
We need to create at least two classes to start testing our plugin. Since we want to see results quickly, let's do the minimum possible here. Let's remember what we want to do here: to add a new "Post-build action" where we can configure the file pattern that we will use to find files to report the test results.
  1. Subclass of hudson.Recorder.
  2. Descriptor class
For 2. there are many options, but we will create a subclass of BuildStepDescriptor<publisher>. More details below.

Resources
  1. config.jelly: jelly code that will be shown in the "Post-build action" section for our plugin
  2. global.jelly: jelly code that will be shown in the Manage Hudson/Configure System section (this file is not used here since we don't have global configuration so far)
  3. help.html: html code with help text for the "Post-build action". This is shown if you click on the ? on the right of your action.
  4. help-artifact.html: html code with help text for the plugin option that will be entered by the user. In our case, the file pattern for the report files.
Results

Files and Details
1. Since our Descriptor class is an inner class, this is the only Java class so far:

src/main/java/com/sacaluta/DistributedTestRecorder.java
public class DistributedTestRecorder extends Recorder {
public static String DISPLAY_NAME = "Distributed Test Report";

private final String report;

@DataBoundConstructor
public DistributedTestRecorder(String report) {
this.report = report;
}

public String getReport() {
return report;
}

public boolean perform(AbstractBuild build, Launcher launcher,
BuildListener listener) {
return true;
}

@Extension
public static final class DescriptorImpl extends
BuildStepDescriptor<publisher> {
@Override
public String getDisplayName() {
return "Publish " + DistributedTestRecorder.DISPLAY_NAME;
}

public void doCheck(StaplerRequest res, StaplerResponse rsp)
throws IOException, ServletException {
new FormFieldValidator.WorkspaceDirectory(res, rsp).process();
}

@Override
public boolean isApplicable(Class arg0) {
return true;
}
}
}
2. Jelly file with the code for our Post-Build action

src/main/resources/com/sacaluta/config.jelly
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:bh="/lib/health">
<f:entry title="Distributed Test Report pattern" field="report"
description="
This is a file name pattern that can be used to locate the Distributed Test report files
(for example <b>**/performance/perf*</b>).<br/>
The path is relative to <a href='ws/'>the module root</a> unless
you are using Subversion as SCM and have configured multiple modules, in which case it is
relative to the workspace root.<br/>
">
<f:textbox />
</f:entry>
</j:jelly>
3. HTML code for help files

src/main/resources/com/sacaluta/DistributedTestRecorder/help.html
(main help file)
src/main/resources/com/sacaluta/DistributedTestRecorder/help-report.html
(help file for "report" configuration field - see above in the config.jelly file)
<div>
This is the distributed test plugin help to be added later.
</div>
Yes, that's all for now. You should already have a post-build action being displayed when you launch Hudson (remember to use "mvn hpi:run" to run Hudson and do not run "mvn package" before that).

Wednesday, April 01, 2009

Guice

0 comments
An interesting dependency injection framework was coded within Google called Guice (you say "juice"). The following video provides a good introduction to it:

http://crazybob.org/2007/06/introduction-to-guice-video-redux.html

I found the following features particularly interesting, which will probably be taken aboard by Spring in the future:
  • Provider: you can inject the provider rather than the dependency. That allows the class to instantiate multiple copies of the class, instantiate the copies lazily or conditionally. Also, if you have dependencies that have different scope (like having a request dependency in a session object), you can handle this case much better.
  • Development stages: this seems to be something for the next version, but it is pretty cool. You can specify beans to be loaded according to the stage (devel/prod), not loading unnecessary beans while you are developing.
  • Constructor listener: another feature for the next version. In short, to be able to intercept the construction of any of the dependencies to be injected.
For a comparison with Spring, check out the following link:

http://code.google.com/p/google-guice/wiki/SpringComparison

I guess it will be hard to come up with a framework to beat Spring, but it seems that Guice and Google products have much better political acceptance and may have better chances of making its dependency injections officially supported in the JDK and sponsored by the JCP.

Update: I found an article that supports my comment above about Web Beans + Guice where one of the readers commented:
There's been a lot of talk over the past few years that perhaps Interface 21 should push to formally make the Spring Framework a part of the JEE specs -- it seemed like it might be possible with Rod Johnson officially declaring his support for JEE 6... well it looks like "Crazy" Bob Lee and the team behind Guice may have found a back door to get themselves into the party first -- according to a new series of articles about the upcoming Web Beans, the new spec is actually influenced by a combination of Seam and Guice ... I find these articles interesting in that Google has apparently taken the JBoss approach to supporting the JCP -- that is, create an independent product to fill a whole in the JEE specs, and then use the JCP to make that product into a spec itself (take a look at the JPA for a previous example)...