Java Moods

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Tuesday, 27 October 2009

Java Mystery: Directory Exists but Does Not?

Posted on 00:47 by Unknown

Well, yesterday for me was another one of those days where you think your computer must be fooling you... There is an issue with a DirectoryCleaner that works for a subproject but does not when called from the parent. But first things first.

The openArchitectureWare Part

We are using oAW (yep, the new version which is part of Eclipse Modeling Project of Eclipse Galileo). Before generating the artifacts from the model, we are executing a directory cleaner that just rubs out the folders, for instance src/generated/java. The workflow file generate.mwe looks like this:

<workflow>
<property file="generateAll.properties"/>
<component class='org.eclipse.emf.mwe.utils.DirectoryCleaner' directory='${srcGenDir}'/>
<component file='.../generateAll.mwe' inheritAll="true">
<modelFile value='...' />
</component>
</workflow>

srcGenDir is a property that is defined in the included properties file, but that's irrelevant. The highlighted line configures the mentioned directory cleaner. The relevant code snippet is invokeInternal() method of org.eclipse.emf.mwe.utils.DirectoryCleaner which is part of Eclipse EMF frameworks:

protected void invokeInternal(final WorkflowContext model, 
final ProgressMonitor monitor, final Issues issues) {
if (directory != null) {
final StringTokenizer st = new StringTokenizer(directory, ",");
while (st.hasMoreElements()) {
final String dir = st.nextToken().trim();
final File f = new File(dir);
if (f.exists() && f.isDirectory()) {
... do the cleanup ...
}
}
}
}

Pretty simple, right? The directory attribute contains one or more directories (comma separated), hence a tokenizer is used to get each of them and to create a file. If this file exists and it's a directory, that will be erased.

The Maven Part

Of course we are using Maven to build the stuff. The Fornax Maven plugin is configured to call the workflow during Maven build. Moreover, the mentioned workflow is part of a subproject B which belongs to an outer multi-module project A.

Now, this is where the mystery begins... When I build B (the submodule), everything is fine and works like expected. However, when I build A (the parent project), B will be built in turn and its workflow is executed, but the directory is not cleaned up! You wouldn't expect this, right?

The Strange Part

In an attempt to find out what's going on, we put some debugging code into DirectoryCleaner. It turns out that the file f returns the same value for getAbsolutePath() in both cases, but f.exists() reveals false when the build is started from the parent project – hence the condition is not met and nothing will be cleaned up.

Unfortunately, you can't look any deeper into the native code that is called when determining if a file exists. So, in a kind of trial and error approach, we found out that using the following code fixes the issue:

protected void invokeInternal(final WorkflowContext model, 
final ProgressMonitor monitor, final Issues issues) {
if (directory != null) {
final StringTokenizer st = new StringTokenizer(directory, ",");
while (st.hasMoreElements()) {
final String dir = st.nextToken().trim();
final File f1 = new File(dir);
final File f = new File(f1.getAbsolutePath());
if (f.exists() && f.isDirectory()) {
... do the cleanup ...
}
}
}
}

That is: by creating another file that is using the absolute path of the first one and using this further on, everything is fine in both scenarios – whether called from parent project or submodule.

To be honest: I have no explanation for these findings. Why is File behaving differently? When calculating the exist flag, the code should take into account the file's absolute path, right? So, why is creation of another file based on the absolute path is fixing the issue? Any insights are deeply appreciated...!

Read More
Posted in Eclipse, Java, Maven, oAW | No comments

Friday, 16 October 2009

Speeding Up Your System

Posted on 04:37 by Unknown

We did a lot of interesting stuff lately, including upgrading Eclipse to the new Galileo release, and in turn upgrading oAW (openArchitectureware) to the new versions of Xtext, Xpand, Xcheck etc. which are now part of the Eclipse Modeling project. I will blog about all this later...

But, what really started to hurt us was the performance of our Windows XP based development laptops. They aren't really brand new ones, but not that old either. Nevertheless, they seem to have an issue with all those java, class and jar files involved when starting Eclipse, doing a "Clean Project", when using Maven to build the software etc.

IT department was not willing to provide us with new hardware (disk especially) at this time, and no, using Linux is no option either. Hence, we had to find out other areas of improvement by tuning our system.

Here is what we did to speed things up for Windows XP. Note that things might or might not be different for Windows Vista or Windows 7.

1. Disable Indexing Service

By default, there is a Microsoft "Indexing Service" running in your Windows system. According to msdn, this is "a base service for Microsoft Windows 2000 or later that extracts content from files and constructs an indexed catalog to facilitate efficient and rapid searching."

Well, to be honest, I have never heard of that service before (and rarely use the search function of Windows), but it turned out to cause lots of harddisk traffic. So we decided to disable this service, which is recommended by some people.

Actually, there are several ways to do so (wihtout using Microsoft Management Console (MMC) with an appropriate snap-in):

  • Disable the Indexing Service in your list of local services.
  • In the Properties window of your local disk, remove option "Allow Indexing Service to index this disk for fast file searching".
  • Remove the function via the Control Panel > Add or Remove Programs > Add/Remove Windows Components > Uncheck "Indexing Service".

2. Don't Virus-Scan Java Stuff

Our anti-virus tool was configured to scan literally everything, including java, class and jar files. This seems to be exaggerated from security point of view, but IT folks said they could not configure the anti-virus to ignore a particular set of file extensions (like *.jar).

Hence, what we did instead was to exclude two folders from being scanned on the fly: javatools (where everything Java related is put, including Eclipse releases) and projects (where all our projects reside). Instead, these folders are now scanned once a week, which is acceptable for IT guys.

Know what? That speeded up starting time of Eclipse by factor 5!

Surprisingly, excluding the Maven local repository (located in your personal settings folder) from being scanned on the fly did not make much difference, so we didn't handle this folder any special.

3. Optimize Subversion

Are you using Subversion? If so, are you using TortoiseSVN, the Windows Shell Extension for Subversion? Well, in that case you will know and probably like the little overlay icons that are used to indicate the state of files and folders. This feature is recursive, whereby overlay changes in lower level folders are propagated up through the folder hierarchy so that you don’t forget about changes you made deep in the tree.

Starting with release 1.2, a new TSVNCache program is used to maintain a cache of your working copy status, providing much faster access to this information. Not only does this prevent explorer from blocking while acquiring status, but it also makes recursive overlays workable.

This is all nice, but there is a major drawback: TSVNCache by default looks for changes on all drives and in all folders, killing disk performance with all the I/O it's doing.

You can enable a TSVNCacheWindow showing all the folders being crawled by TSVNCache. To do so, open the Registry Editor, and create a new DWORD at HKEY_CURRENT_USER\Software\TortoiseSVN\CacheTrayIcon with value of 1. After that you have to restart TSVNCache which is easiest done by just killing the process, it will be automatically restarted when you do any TortoiseSVN operation. Now there should be a small tortoise icon in Windows tray area which opens the TSVNCacheWindow. Watch how TortoiseSVN scans files and folders whenever you write to a file...

Time to fix that! That should be quite easy if you're keeping all of your working copies below one specific folder (or a small set of folders), like we do. All you have to do is to setup TortoiseSVN to only scan your sourcefolder paths:

  1. Right-click in Explorer on any folder and select "TortoiseSVN > Settings...".
  2. In the Settings window's tree, click on the "Icon Overlays" entry.
  3. In the "Exclude Paths" input field, put C:\* to exclude the entire C drive. If you have more drives, exclude them all at the top level. Use newlines to separate the values.
  4. In the "Include Paths" input field, list all of the locations where your working copies are stored, again separated by newlines.
  5. Switch off "Network drives" option in "Drive Types" area.

All in all, your settings should now look like in the following screenshot. Thanks to Paraesthesia for this nice tip!


Epilogue

You won't believe what difference these three little tunings made to our system performance. The harddisk is not any more busy all the time, applications (like Eclipse) are starting much faster, and build time has decreased drastically. Not bad for not spending anything on new hardware! Well, next thing we will check is what effect a new (big, fast) hard disk will have... ;o)

Read More
Posted in Performance, Windows | No comments

Thursday, 17 September 2009

Spring: Use Custom Namespaces!

Posted on 23:30 by Unknown

Have you ever heard of custom XML namespaces for Spring? I know you love Spring (like I do), so... probably yes. They are available since Spring 2.0 which came out October 2006, so I just can't believe we didn't use them up to now.

The Old-Fashioned Way

Well, we are building our web apps on JSF and Spring Web Flow, and additionally use a custom framework for adding a few more features like mapping between business objects and view objects based on XML mapping descriptions. Of course, this framework part is designed "IoC friendly", i.e. it's based on interfaces and standard implementations that need to be plugged by Spring configuration.

We did this by providing a basic Spring configuration that defines defaults for most elements and injects all required references into the main configuration objects. To allow the project to provide custom implementations, this code relies on particular bean names that have to be defined by the custom project. Here's a simple example for the framework's configuration:

<bean id="iplIntegrationInfo" class="...IntegrationInfo">
<!-- myViewObjAccessor: to be defined in project specific Spring config file -->
<property name="viewObjAccessor" ref="myViewObjAccessor" />
<!-- myContextResolver: to be defined in project specific Spring config file -->
<property name="contextResolver" ref="myContextResolver" />
...
</bean>

<!-- These can be used for aliases if standard implementation should be used -->
<bean id="defaultViewObjAccessor" class="..." />
<bean id="defaultContextResolver" class="..." />

As you can see, all references are injected into the main configuration (iplIntegrationInfo). However, the referenced beans are not actually defined but have to be provided by the project. So, here's an example for the project's configuration:

<!-- use default -->
<alias alias="myViewObjAccessor" name="defaultViewObjAccessor" />

<!-- use custom implementation -->
<bean id="myContextResolver" class="..." />

Here we use the default for the first bean (by just establishing an alias for the configuration done in the framework file), and a custom implementation for the second.

This approach works, but obviously has a few drawbacks:

  • Configuration is shared between framework and project specific configuration code.
  • Project needs to know the framework's Spring file to do its work.
  • Internal framework structures (bean names, classes) are exposed to the outside.
  • A lot of XML code is required, even if using all the defaults.

Using Custom Namespaces

What should I say, we have switched to custom namespace lately and now configuration looks like this:

<ui:view-config/>

That's as short as it can be, but still is a complete configuration in case the project is using default implementations for all the beans. If the project would like to override some settings, the configuration file may be:

<ui:view-config>
<ui:viewobj-accessor ref="viewObjAccessor"/>
<ui:context-resolver ref="contextResolver"/>
</ui:view-config>

<bean id="viewObjAccessor" class="..." />
<bean id="contextResolver" class="..." />

Hence, you have the option to override all default implementations, and use meaningful tags to do so. Can you see the gains?

How Does This Magic Work?

I'm not going to provide full description on how to author custom namespaces since that is available in the Spring reference documentation and elsewhere. So, just a few basics to give you the idea...

First of all, you have to provide an XML schema describing your namespace. Then you have to implement a Namespace Handler that links each tag of your namespace to an XML parser, the Bean Definition Parser. And then, of course, those parsers must be implemented.

Each bean defintion parser is supposed to parse the XML element (including all attributes and sub elements) and to build the appropriate Spring beans. Spring provides a small hierarchy of classes you can use, depending on your situation:

  • The most specific is AbstractSimpleBeanDefinitionParser that fits well when there is a strong correlation between the attributes on a tag and the properties on your bean. In this case, there is really few code on your side.
  • The AbstractSingleBeanDefinitionParser is a bit more general, it allows you to create any single bean definition for an arbitrary complex nested XML structure. This involves more coding, of course, but still does some work for you (like automatically registering the bean in the context). This is the one you'll probably use most of the time.
  • The AbstractBeanDefinitionParser is even more general and allows you to create multiple bean definitions and register them directly. It takes care of id generation and a few other things.
  • Instead of using the latter one, you could also implement the BeanDefinitionParser interface directly, giving you all the flexibility you need.

All in all, you'll need a few hours to get comfortable with all the classes that are used to build up the bean definitions (DomUtils, BeanDefinition, BeanDefinitionBuilder, RuntimeBeanReference and ManagedMap/ManagedList to name a few).

But after that, building the parser and creating/registering your beans is quite straightforward. Moreover, you always can sneak a peek on how Spring itself is doing it for the Spring provided custom namespaces (like for Spring Security, for instance).

Okay, that's all for now, so go ahead and make life easier for your customers, your team, or yourself by providing a well-designed custom Spring namespace!

Read More
Posted in Spring | No comments

Tuesday, 8 September 2009

Spring: Test Framework Never Heard of Web Apps?

Posted on 02:31 by Unknown
Do you know the Spring TestContext Framework? You really should. It drastically simplifies JUnit-testing of Spring powered applications. One particular cool thing is that it offers an easy, annotation based way to load your Spring context and auto-wire your beans. For example, this is how it could look like for JUnit 4:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-config/ui-test-config.xml")
public class MyParticularTest {
@Autowired
private Controller controller;
...
}

This is really nice, but... there is one thing we stumbled upon lately.

The test framework by default is using the GenericXmlContextLoader which loads the Spring application context as an instance of GenericApplicationContext. This class, obviously, is not aware of web applications that would require a WebApplicationContext instead. Hence, you can't access any web related resources, use associated scopes etc.

Don't get me wrong... Spring TestContext Framework is nice, but it's more than strange that it does not support the web scenario. There is a Jira issue for that, but it's still open for more than 10 months now, and is scheduled not until Spring 3.1?!? That's just annoying.

Well, there are some workarounds of course, based on using a custom context loader. See this blog post or this Spring community thread, for instance.

Read More
Posted in JUnit, Spring, Testing | No comments

Highlight your Syntax

Posted on 00:53 by Unknown

Now, summer is nearly over and I'm back on this blog. During summer time, I use to spend more time with my family (and doing vacation ;-) but now my head is full with lots of snippets that could make it into this blog.

First of all, I have integrated some syntax highlighting to these pages. This might be well-known and boring for you, but I didn't really know how to do this until finding Alex Gorbatchev's SyntaxHighlighter. It's purely based on JavaScript and hence can be easily integrated with lots of products, tools and engines – like Blogger.com. Integration couldn't be easier, see here for a step-by-step explanation.

When adding code, you just have to give your <pre> element a class like this: <pre class="brush:java">. That's it!

What do you get by this? Well, the well-known, nicely formatted code blocks like this one

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exists.
MethodOverrides methodOverrides = getMethodOverrides();
if (!methodOverrides.isEmpty()) {
for (Iterator it = methodOverrides.getOverrides().iterator(); it.hasNext(); ) {
MethodOverride mo = (MethodOverride) it.next();
prepareMethodOverride(mo);
}
}
}

This works for lots of languages (called "brushes"), including XML and JavaScript, and you can easily provide a custom brush. Standard layout can be customized, of course, but the default is pretty good IMO.

There are just two or three things (there is always room for improvements ;-)

  • Syntax Highlighter documentation is a bit sparse...
  • The server hosting the CSS and JavaScript files, http://alexgorbatchev.com, seems to be not the fastest one. To speed up things, the Syntax Highlighter files could be hosted somewhere else, and they most probably already are.
  • You can highlight particular lines using the <pre class="brush:java; highlight: [14, 15]"> syntax (see line 7 in example above). However, it seems you can't specify areas but have to list all individual lines which might be cumbersome.

All in all, pretty cool. Syntax Highlighter is open source under LGPL 3, but the author asks you to "buy him a beer" if you use his tool. Well, I honestly will think of some donation ;-)

Read More
Posted in | No comments

Tuesday, 23 June 2009

Maven: How Relocated Artifacts Can Ruin Your Day

Posted on 06:25 by Unknown

Wow, this is one of those days I struggle with issues all the time without actually going forward one little bit on my original task... I guess you all know this feeling :o(

Now, one of the things that I wasted quite some time on is excluding a dependency. One of our modules is defining a dependency to Apache DBCP framework like this:

<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.1</version>
</dependency>

This dependency is transitively depending on some XML artifacts, which you can see by using the maven-dependency-plugin's tree goal:

...
[INFO] +- commons-dbcp:commons-dbcp:jar:1.2.1:compile
[INFO] +- commons-pool:commons-pool:jar:1.2:compile
[INFO] +- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] \- xerces:xercesImpl:jar:2.0.2:compile
...

Well, the xml-apis and xerces artifacts are a bit outdated and actually we didn't want them at all in our war files, so I decided to exclude them using the dependency exclusion feature:

<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<artifactId>xml-apis</artifactId>
<groupId>xml-apis</groupId>
</exclusion>
<exclusion>
<artifactId>xerces</artifactId>
<groupId>xercesImpl</groupId>
</exclusion>
</exclusions>
</dependency>

What do you think will be the result? Surprisingly, xml-apis:xml-apis vanished, but xerces:xercesImpl didn't. The new dependency tree is the evidence:

...
[INFO] +- commons-dbcp:commons-dbcp:jar:1.2.1:compile
[INFO] +- commons-pool:commons-pool:jar:1.2:compile
[INFO] \- xerces:xercesImpl:jar:2.0.2:compile
...

That's strange, isn't it? It took me an hour or so playing around to find the reason for this behaviour: Xerces has been relocated with respect to its Maven coordinates... The only hint Maven is giving you is this message when executing in debug mode:

[DEBUG] While downloading xerces:xerces:2.0.2
This artifact has been relocated to xerces:xercesImpl:2.0.2.

What does that mean? Well, you may relocate artifacts in the Maven repository when the group or artifact id should change (for more details, see the Guide to Relocation). Originally, the DBCP artifact specified a dependency to xerces:xerces in its dependencies – which you can see in the artifact's POM file (residing in your local Maven cache, for instance):

<dependency>
<groupId>xerces</groupId>
<artifactId>xerces</artifactId>
<version>2.0.2</version>
</dependency>

However, xerces:xerces has been relocated to xerces:xercesImpl and these new coordinates are what is shown in the dependency tree. But, when excluding a dependency, you must specify the original transitive dependency (as defined by the artifact), not the new coordinates:

<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<artifactId>xml-apis</artifactId>
<groupId>xml-apis</groupId>
</exclusion>
<exclusion>
<artifactId>xerces</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>

How intuitive is that???

Maven should really do better, either by indicating the original coordinates when showing the dependency tree/list, or better yet by issuing a warning when trying to exclude a relocated dependency. I guess the latter one is not easy to implement, but current solution is just annoying!

Read More
Posted in Maven | No comments

Wednesday, 17 June 2009

Checkstyle: One and Only Configuration File?

Posted on 07:33 by Unknown

The Checkstyle Challenge

When you are using both Eclipse and Maven, you are probably facing the same challenge like we do: you would like to have a single configuration file for Checkstyle tool and reference that in Eclipse as well as in Maven.

Checkstyle ships with some default conventions (according to the Sun coding standards). But you usually want to customize this and create your own configuration set, based on your corporate coding styles.

Now, you want to setup Checkstyle within Eclipse to provide direct feedback to developers. You want to setup Checkstyle with Maven to be able to have a coprehensive report built as part of your project site. And you want both to reference the same configuration file, to avoid having to maintain two of them. Naturally, right?

Well, unfortunately, it seems impossible to achieve... if you really found a way, let me know!

However, there nonetheless are some tips to help you having a centralized configuration of Checkstyle with both tools. This post is about how to do that.

Checkstyle with Maven

The goal is to centralize the Checkstyle configuration to make its usage as simple as possible for all the projects, avoiding manual configuration as far as possible. Fortunately, this is quite easy using Maven's dependency mechanism.

Essentially, we build a custom artifact that contains nothing but our Checkstyle configuration file. This JAR is deployed to the company's Maven repository from where it can be downloaded as a normal dependency when needed. After that, the Checkstyle plugin is configured (in the reporting section) to reference the packaged configuration file. That's it!

Now, we'll look at the details...

Let's assume our checkstyle configuration is located in config/my-checkstyle.xml. Then the POM of the checkstyle artifact, which actually is a minimal Maven project, looks like this:

  ...
<groupId>com.fja.ipl</groupId>
<artifactId>checkstyle-config</artifactId>
<version>1.0</version>
<build>
<resources>
<resource>
<directory>config</directory>
</resource>
</resources>
</build>
...

(Of course, you additionally have to add the distributionManagement section to be able to deploy the artifact, but this is usually derived by the company's base POM.)

Deploy the artifact. You'll notice that the created checkstyle-config-1.0.jar indeed contains your my-checkstyle.xml file in its root.

Now let's switch to the project that should use the Checkstyle report. The configuration file is referenced in the Checkstyle plug-in configuration in the reporting section like this:

  <reporting>
<plugins>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.2</version>
<configuration>
<configLocation>my-checkstyle.xml</configLocation>
</configuration>
</plugin>
...
</plugins>
</reporting>

That is not yet working, Maven can't find this file – our checkstyle-config artifact has not been referenced. We do this now by adding it as an extension dependency to the POM as follows:

  <build>
<extensions>
<extension>
<groupId>com.fja.ipl</groupId>
<artifactId>checkstyle-config</artifactId>
<version>1.0</version>
</extension>
</extensions>
...
</build>

The artifacts configured as extensions will be included in the running build's classpath. That means, checkstyle-config-1.0.jar now is in the classpath of the Checkstyle plugin, and the file referenced by the configLocation setting is located in the JAR and hence can be found.

Using this approach, the Checkstyle configuration can be maintained centrally, and projects can get new versions simply by updating the artifact's version in the extension section.

Checkstyle with Eclipse

Unfortunately, I don't really see a way to use the same Checkstyle configuration, packaged into the Maven artifact, with Eclipse as well...

So you'll have to duplicate the configuration file. However, to keep the number of duplicates small, I recommend to put it on a central network drive within your company and use the Remote Configuration option of the Checkstyle Eclispe plugin to reference the remote file. This does not prevent you from working offline because Eclipse downloads and caches this file.

In this scenario, changing the Checkstyle configuration is done centrally by just updating the remote file. This is a great advantage over using a configuration that is part of the project, because in the latter case you would have to upgrade every single project.

Read More
Posted in Checkstyle, Eclipse, Maven | No comments
Newer Posts Older Posts Home
Subscribe to: Posts (Atom)

Popular Posts

  • The Butler Dispute, Round 2
    Nearly 4 month have passed by since the renaming of Hudson project to Jenkins, which marks the climax of the dispute between the old Hudson...
  • World of Versioning
    Today, we had a discussion on how to name a hotfix release of our framework product, built with Maven (you knew I'm a fan of Maven, didn...
  • The Way From Hudson To Jenkins
    Some time has gone by since the Hudson/Jenkins fork ... and there has been even more talk in the community. However, slowly the dust settles...
  • Maven Setting for Using a Single Repo Manager
    In a previous post I have tried to explain why it's a good idea to define your Maven repository in your settings.xml file instead of t...
  • Maven Enforcer Plugin: cool and annoying
    As a Maven expert, you probably have heard of maven-enforcer-plugin , "The Loving Iron Fist of Maven", as they say. It's so co...
  • Having Fun with Encoding!
    Compiler Plugin Recently, I edited our main company root POM to upgrade some plugins to new versions. Of course, we are following best pract...
  • Spring: Use Custom Namespaces!
    Have you ever heard of custom XML namespaces for Spring? I know you love Spring (like I do), so... probably yes. They are available since Sp...
  • Eclipse: User Operation is Waiting, and Waiting, ...
    I am using Eclipse since quite a long time, sometimes around 2002. That was version 2.0, if I remember correctly. Since then, I have always ...
  • Maven Plugin Releases: Do it yourself!
    In my previous post , I have complained about Maven plugins that do not release new versions although there are blocking issues that are rep...
  • Highlight your Syntax
    Now, summer is nearly over and I'm back on this blog. During summer time, I use to spend more time with my family (and doing vacation ;-...

Categories

  • BestPractices
  • Cargo
  • Checkstyle
  • Eclipse
  • Google
  • Hudson
  • Java
  • JBoss
  • JEE
  • Jenkins
  • JUnit
  • Maven
  • Nexus
  • oAW
  • Optimization
  • OSGi
  • Performance
  • Profiles
  • QA
  • Size
  • Spring
  • Testing
  • Tools
  • WebApp
  • Windows

Blog Archive

  • ▼  2011 (5)
    • ▼  May (1)
      • The Butler Dispute, Round 2
    • ►  April (1)
    • ►  March (2)
    • ►  February (1)
  • ►  2010 (11)
    • ►  October (2)
    • ►  September (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (4)
    • ►  January (2)
  • ►  2009 (30)
    • ►  December (3)
    • ►  November (4)
    • ►  October (2)
    • ►  September (3)
    • ►  June (4)
    • ►  May (5)
    • ►  April (4)
    • ►  March (5)
Powered by Blogger.

About Me

Unknown
View my complete profile