12/23/2009

HireBug

On the last DevClub meeting I presented a HireBug - a "server-side Firebug".

This is presentation in russian:
http://www.slideshare.net/asolntsev/hire-bug

Update: presentation video (also in russian):
http://www.devclub.eu/2009/12/29/andrei-slontsev-hirebug/

11/27/2009

Vaadin demo with Maven

I like Vaadin - Java web framework created by Finnish guys from ITMill.

Vaadin homepage: http://vaadin.com

This is demo web application built with Vaadin+Maven which performs search files on server.
It was really easy to create it!



All you need is to include Vaadin depenency to your pom.xml and create class that extends com.vaadin.Application. No any XMLs, jsp etc.


Full source code:
http://dl.dropbox.com/u/2856647/vaadin-demo-webapp.zip

Screencast:
http://dl.dropbox.com/u/2856647/VaadinDemo.swf

Short overview of Vaadin: http://www.streamhead.com/vaadin-promote-great-gwt-toolkit/

11/26/2009

Jetty Runner

What is JettyRunner?
Jetty Runner is an Eclipse plugin that allows developer to easy run web applications from your projects.

How it works
- Scan all projects in workspace
- Detect web applications projects
- Let user choose web applications to run
- Let user choose the database to connect to
- Run Jetty

Presentation
http://www.slideshare.net/asolntsev/eclipse-jetty-runner

Screencast
http://dl.dropbox.com/u/2856647/JettyRunnerDemo.swf

Installation
Write me in comments if you are interested. Then I will publish the sources/binaries.

PS. This plugin was presented at Eclipse DemoCamp in Tallinn 27.11.2009

5/20/2009

ThreadSafeDateFormat

Problem
As known, Java class SimpleDateFormat is not Thread-safe.
It means that you cannot declare a static member DateFormat in class:

private static final DateFormat DATE_FORMAT = new SimpleDateFormat( DATE_PATTERN ); // WRONG!

Using this member by 2 concurrent treads will lead to error.

What is a solution?
One solution is to create new SimpleDateFormat( DATE_PATTERN ) each time you need to parse a date. Another solution is to create a Thread-safe version of DateFormat.

That's it:


import java.lang.ref.SoftReference;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* Thread-safe version of java.text.DateFormat.
* You can declare it as a static final variable:
*
* private static final ThreadSafeDateFormat
* DATE_FORMAT = new ThreadSafeDateFormat( DATE_PATTERN );
*/
public class ThreadSafeDateFormat extends DateFormat
{
private static final long serialVersionUID = 3786090697869963812L;

private final String m_sDateFormat;

public ThreadSafeDateFormat(String sDateFormat)
{
m_sDateFormat = sDateFormat;
}

private final ThreadLocal m_formatCache = new ThreadLocal()
{
public Object get()
{
SoftReference softRef = (SoftReference) super.get();
if (softRef == null || softRef.get() == null)
{
softRef = new SoftReference(
new SimpleDateFormat(m_sDateFormat) );

super.set(softRef);
}
return softRef;
}
};

private DateFormat getDateFormat()
{
return (DateFormat) (
(SoftReference)m_formatCache.get()).get();
}

public StringBuffer format(Date date,
StringBuffer toAppendTo, FieldPosition fieldPosition)
{
return getDateFormat().format(
date, toAppendTo, fieldPosition);
}

public Date parse(String source, ParsePosition pos)
{
return getDateFormat().parse(source, pos);
}
}



The main idea of this class is storing separate instances of SimpleDateFormat for separate Threads in ThreadLocal variable. If 2 concurrent threads try to parse date, the will use 2 different instances of SimpleDateFormat.

3/14/2009

Functional Programming in Java

This is my seminar about Functional Programming and using its ideas in Java.

It was done in year 2006.

http://www.slideshare.net/asolntsev/functional-programming-in-java

8/10/2008

proxy-scm sources

As some people ask, I publish my sources of maven-scm which include proxy-scm feature.

You can either build it from sources, or upload binaries to your company/local repository.

Sources (downloaded from apache source repository and modified):
http://andrei.solntsev.googlepages.com/maven-scm-1.1.Internal-sources.zip

Binaries (built with JDK 1.5, compatible with JDK 1.4):
http://andrei.solntsev.googlepages.com/maven-scm-1.1.Internal-binaries.zip

If you build from sources, you need to change section in pom.xml files.

To start using this modified version of maven-scm plugin, you need to write it into your pom.xml's "pluginManagement" section:

<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.1.INTERNAL-SNAPSHOT</version>
</plugin>
</plugins>
</pluginManagement>

3/05/2008

How to find which jar file contains your class at 'runtime'

It's often happening when you want to get know where JVM takes some class from.
If this class potentially can be located in several folders/jars, you never know which one of them JVM uses.

There is a simple method allowing this:

/**
* Method returns code source of given class.
* This is URL of classpath folder, zip or jar file.
* If code source is unknown, returns null (for example, for classes java.io.*).
*
* @param clazz For example, java.sql.SQLException.class
* @return for example, "file:/C:/jdev10/jdev/mywork/classes/"
* or "file:/C:/works/projects/classes12.zip"
*/
public static String getCodeSource(Class clazz)
{
if (clazz == null ||
clazz.getProtectionDomain() == null ||
clazz.getProtectionDomain().getCodeSource() == null ||
clazz.getProtectionDomain().getCodeSource().getLocation() == null)

// This typically happens for system classloader
// (java.lang.* etc. classes)
return null;

return clazz.getProtectionDomain()
.getCodeSource().getLocation().toString();
}

2/09/2008

Extending Maven SCM: proxy-scm

Problem description

Maven is a great tool, but it has one constraint that makes it inapplicable in many cases.
It can checkout the whole project (pom.xml and sources) from a single place in SCM storage using a single tag.

It's quite suitable in open-source projects, where new versions of projects don't appear too often.
But in our company we have a lot of components, each of which is stored in its own place in SCM and tagged with its own tag. To make using Maven possible, we need to create either BASH or ANT script which would check out all required projects from SCM.

This is the concern:

why do I need Maven if i still need ANT for running it?

If only Maven could do it by itself...

After thinking a while, we have created a solution.

Solution

As known, Maven SCM plugin has several SCM providers: CVS, Subversion, ClearCase etc.
Idea is to create one more provider, Proxy SCM. Its main goal is to checkout different modules from different places calling other SCM providers.
We need to extend pom.xml with 2 attributes:
  • /project/modules/module@scmProvider
  • /project/modules/module@scmHost
  • /project/modules/module@path
  • /project/modules/module@tag


Given pom.xml of form:

<project>
<scm>
<connection>scm:proxyscm:cvs:pserver:@myhost:dir:nodule</connection>
<developerConnection>scm:proxyscm:cvs:pserver:bla-bla</developerConnection>
</scm>
<modules>
<module path="robots/terminator/sdk">terminator_sdk</module>
<module path="robots/terminator/ui" tag="terminator_ui_v1-2">terminator_ui</module>
<module scmProvider="svn" scmHost="http://svn.apache.org/repos/asf/commons/proper/launcher" path="trunk">commons_launcher</module>
</modules>
</project>
,

The proxy-scm provider checks out all the 3 projects into 3 subfolders in current folder, resulting in the following content:
  • pom.xml
  • terminator_sdk
  • pom.xml
  • src
  • terminator_ui
  • pom.xml
  • src
  • commons_launcher
  • pom.xml
  • src


Implementation

The code of proxy-scm provider is quite simple: it just needs to parse file "pom.xml" and call appropriate SCM provider for every module.

I would like to commit this code into the next Maven SCM version (1.1). But it seems those guys don't respond to JRA issues neither commit patches into new version :(

2/08/2008

Null-Initialization in Java

In many languages (C++), uninitialized variables lead to errors. So, it's considered to be a good style to initialize every variable with 0 or null.

however, in Java it's quite the opposite.
Initialization with null is not recommended for those class members that should not be null.

Instead, it's recommended to declare those members final and initialize only once with an adequate value.


See example below.


Bad practice:

private CCollectorTarget m_collectTrg = null;

private CCollectorSchema m_collectSchm = null;

private CCollectorProject m_collectPrj = null;

private CCollectorFiles m_collectFiles = null;

public CCollectorData( CCollectorTarget collectTrg,
CCollectorSchema collectSchm,

CCollectorProject collectPrj,

CCollectorFiles collectFiles )

{

m_collectSchm = collectSchm;
m_collectTrg = collectTrg;
m_collectPrj = collectPrj;
m_collectFiles = collectFiles;
}

Good practice:

private final CCollectorTarget m_collectTrg;
private final CCollectorSchema m_collectSchm;
private final CCollectorProject m_collectPrj;
private final CCollectorFiles m_collectFiles;

public CCollectorData( CCollectorTarget collectTrg,
CCollectorSchema collectSchm,

CCollectorProject collectPrj,

CCollectorFiles collectFiles )

{

m_collectSchm = collectSchm;
m_collectTrg = collectTrg;
m_collectPrj = collectPrj;
m_collectFiles = collectFiles;
}

This technique has additional advantages: java compiler detects cases when you

  1. forget to initialize variable, or
  2. try to initialize it more than once.