Tuesday, October 23, 2007

Relating UML to Java

A couple of weeks ago I wondered about a strange Java phenomenon: when I create a class Book, it is automatically inherited from Object.
Look at this little class diagram:


This is quite weird if you think about this a little longer. My Book is not a living thing, it is just a template for all the real books I want to create (aka instantiate).

What I (and maybe you too) would expect, is that Book is just a Class, and a physical book (e.g. The Hobbit) would be an Object.
I painted that below:

You can see here that my Book is a subclass of Class, and my book "The Hobbit" is an Object.
Also, my book "The Hobbit" has been instantiated from Book.

At this moment, i can't fully assert the correctness of my statement, and the consequences. Maybe the reader has some ideas, and want to share them?

I'm am also preparing a post about stereotypes in the UML Metamodel, which has some relation with this post, so stay tuned!

Monday, August 27, 2007

Speedup development by making spring beans lazy

In the Spring Framework you can specify on a bean level, or on a bean xml, that a bean must be instantiated lazily.

Of course you do not want to this in production, because the beans should be instantiated at deploy time, not slow down the requests of an innocent end user.

But it can be a handy feature when you use it for deployment time: it speeds up your build cycle, because beans you don't touch by your request, aren't instantiated at all.
Now we do have a problem: how can we set all beans to lazy-init="true" without doing this in production.
You can alter all context files and add the lazy-init="true" to all bean definitions, or even add the default-lazy-init="true" on the outer beans XML element. But when you go into production mode you have to change everything back which can be a pain in the **s.

I found a little solution which programmatically marks all beans as lazy. This is done by a subclass of the normal XmlWebApplicationContext, which overrides the loadBeanDefinitions method. It also has an attribute to specify beans which we do want to preinstantiate: e.g. the SessionFactory because we always need that one.

public class LazyXmlWebApplicationContext extends XmlWebApplicationContext {

private List<String> preInstantiableBeans = Arrays.asList(new String[] {"sessFactory"});


/**
* @see org.springframework.web.context.support.XmlWebApplicationContext
*/
protected void loadBeanDefinitions(XmlBeanDefinitionReader aReader)
throws IOException {
super.loadBeanDefinitions(aReader);

String[] beanDefinitionNames =
aReader.getBeanFactory().getBeanDefinitionNames();
for (int i = 0; i < beanDefinitionNames.length; i++) {
String name = beanDefinitionNames[i];

AbstractBeanDefinition beanDefinition =
(AbstractBeanDefinition) aReader.getBeanFactory()
.getBeanDefinition(name);

if (!this.preInstantiableBeans.contains(name)) {
beanDefinition.setLazyInit(true);
}

}
}
}
You can register this webapplication context in the web.xml (again, only development time!):
<context-param>
<param-name>contextClass</param-name>
<param-value>mypackage.LazyXmlWebApplicationContext</param-value>
</context-param>

Startup performance now increases with about 25% (avg application), have Fun!

Saturday, August 25, 2007

Java Summer Camp 2007

Last Friday I attended the Profict Java Summer Camp 2007.
This camp dealed with JRuby and Grails.

First we had a short intro by our host: Profict. They had a little talk about their company

The first session was about JRuby on Rails by Charles Nutter.
In his talk he (t/w)alked through the basics of Ruby and Jruby itself, and after that, through the JRuby on Rails part.
JRuby tries to bring the power of the Ruby programming language to the Java world. The JRuby code is interpreted by the JVM at runtime.
I saw a particular useful feature in the demo in the second part: the 'migration' stuff: at any time you can migrate your underlying database to a newer or older version.
At this point, deployment is not top notch yet imho: The current method is Mongrel, which has the disadvantage that you have to start x instances in order to have x threads, leading to memory problems.
They are also working on real applicationserver integration, to have threads as provided by the JVM, which is of course a lot better (also for the acceptance in enterprises).


The second session was about Grails by Graeme Rocher.
He had a split up as well: first he talked about the language Groovy.
Groovy really is a scripting language for Java. The difference with JRuby is, that Groovy code is compiled to bytecode (It is not interpreted at runtime). That makes integration with other normal Java classes easier.

In the second part he showed Groovy on Rails: Grails
The functionality is very similar to the functions of JRuby on Rails, but there are (in my opinion and what I saw) positive differences: with grails it's is possible (at least in the demo) to create taglibs in an easy way compared to the current J2EE way.
Also the real hot deployment and code replacement (grails uses an advanced own classloader) is a nice option.
But the biggest advantage I think, is the fact Groovy is closer the the Java world than JRuby, which makes it easier for developers to pick it up.


After the sessions we had a delicious BBQ, and enough time to talk to other attendants :)
Thanks to Profict for this Java Summer Camp!

Monday, August 6, 2007

Natural sorting for strings

This weekend I was struggling with a sorting issue: sorting strings the natural way.

From an file I had read lines (Strings) and then wanted to sort some pieces of the lines.
This is an oversimplified piece of the code:
String[] array = new String[] { "1", "10", "2" };

What a wanted is that the 10 would be placed at the end.
An Arrays.toString(array)now results in "[1, 10, 2]", not what I want to.

Stubborn as I am, i did not want to Integer.parseInt() the elements, which would kill the elegance of the code.

There was nothing in the Java API docs closely resembling this sorting stuff, but I found a nice solution on the Internet which I want to promote. Stephen Friedrich created an utility class which provides the sorting algorithms I was looking for.

I now can use this class this way:
Arrays.sort(array, Strings.getNaturalComparator());
System.out.println(Arrays.toString(array));

The Arrays.toString(array)now results in "[1, 2, 10]", which I wanted to see.
This is very comfortable to read, and also what people expect (therefore called Natural Sorting).

Kudos to Stephen for this nice piece of code. But I feel this kind of sorting should be part the standard Java API.

Tuesday, July 17, 2007

Trouble opening faces configuration files in Eclipse WTP

I wanted to upgrade to the new version 3.3 of eclipse, including WTP 2.0.
Upgrade went fine, except for one thing: opening faces configuration files.

I was eager to fully use the functionality provided by WTP. (My previous WTP version was quite buggy, so i did not use that one.) For this I have a maven war project based on the standard(?) maven war layout:
- src / main / java
- src / main / webapp
And of course the test and resources directory, but forget about those now.

In my pom.xml I added some configuration options to the maven-eclipse-plugin, so my project metadata should be autogenerated:
<additionalprojectfacets>
<jst.jsf>1.1</jst.jsf>
</additionalprojectfacets>
<wtpversion>1.5</wtpversion>
The buildCommands and natures in the .project file will be generated by the maven-eclipse plugin because I did provide a wtpversion tag. (It says 1.5 , but it should be forward compatible to 2.0).

After running mvn eclipse:clean eclipse:eclipse i tried to open one of the faces configuration files located in /src/main/webapp/WEB-INF/faces, say my-config.xml , but got an error:


The .log file says:
!ENTRY org.eclipse.core.jobs 4 2 2007-07-17 21:42:07.500
!MESSAGE An internal error occurred during: ""Loading faces-config model"".
!STACK 0
org.eclipse.core.runtime.AssertionFailedException: assertion failed:
at org.eclipse.core.runtime.Assert.isTrue(Assert.java:109)
at org.eclipse.core.runtime.Assert.isTrue(Assert.java:95)
at org.eclipse.jst.jsf.facesconfig.ui.ModelLoader$ModelLoaderJob.loadModel(ModelLoader.java:165)
at org.eclipse.jst.jsf.facesconfig.ui.ModelLoader$ModelLoaderJob.run(ModelLoader.java:122)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)


After some keyboard-head-banging i found out the problem: the webapp directory should not be under /src/main but on the root level; as a sibling of src.
I don't know if i should submit a bug report to the WTP guys, maybe I'll do when i get some confirmation.

For the maven lovers, this pom config snipped helped me out:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>webapp</warSourceDirectory>
</configuration>
</plugin>
As you can see i did override the web directory setting (standard configured to /src/main/webapp) to webapp.

If you don't use maven, just move that webapp (or whatever name) to the root, and change in /.settings/org.eclipse.wst.common.component the "deploy path / entry" to:
<wb-resource deploy-path="/" source-path="webapp"/>

Thursday, July 12, 2007

Site generation with maven

Today I wanted to generate a site with maven.

Normally you execute the command mvn site:site to generate a nice site for your java project. This way you can see all kinds of nice statistical information about your code and that of your team members. E.g. you can see test coverage results made by the cobertura plugin, and other nice reports.

I notice two things here:
  1. What happens when you are going to make your site fancier with e.g. checkstyle plugin provided with your own checkstyle rules? Then you have to hack the pom.xml file(s) in order to get access to the rules (needs to be on the classpath).
    This way you have to add extra dependencies in your pom.xml which are not necessary for the normal coding tasks.
    Not only for the checkstyle plugin, but for many other plugins (e.g. the spring beandoc plugin which looks at the classpath for a spring config file)
  2. A fairly large java project combined with quite a few maven reporting plugin will take much site-generation time. A single site:site can cost you up to an hour. Normally, busy developers don't want to wait such a long time.
I thus recommend an approach that takes care of both problems: create an profile in your pom.xml exclusively for the site generation. Assign that profile an useful <id/> e.g. <id>siteGen</id>.
Now you can generate your site using mvn -P siteGen site:site ; this time without interfering with all other xml stuff in your pom.xml
And you can let the buildserver do its job: building. Generating a site on the buildserver can be done a limited times per day, using the described profile way.