Archive for the ‘Java’ Category

Jackrabbit on the Run

Friday, October 30th, 2009

This post is a brief guide on how to get Apache Jackrabbit and to write an Eclipse plugin that works with it.

Jackrabbit is an open source implementation of the Java Content Repository defined in JSR 170. Current stable version is 1.6.0 and they have alpha builds of 2.0 version that should implement JSR 283, the next revision of the JCR.

Running Jackrabbit is easy: download jar with standalone server jackrabbit-standalone-1.6.0.jar and launch it:

dimzzy@hornet:~ $java -jar jackrabbit-standalone-1.6.0.jar
Welcome to Apache Jackrabbit!
-------------------------------
Using repository directory jackrabbit
Writing log messages to jackrabbit/log
Starting the server...
Apache Jackrabbit is now running at http://localhost:8080/

After this Jackrabbit will create a JCR repository with default workspace and you may connect to it from a web browser at http://localhost:8080/.

The next step is to put in some data. You may do it right within the browser by following the Populate link and harvesting internet for data or by mounting WebDAV directory http://localhost:8080/repository/default/ and copying some files and folders there. Default administrator account is admin/admin.

Accessing Repository

Now launch Eclipse and create a new plugin project. Our client will be a simple repository browser that shows a tree of nodes so add a view part with a TreeViewer. To use JCR API we will also need a jar (jcr-1.0.jar) with all the classes and interfaces which you can download here: JSR 170 downloads.

In order to connect to the running Jackrabbit you will need three more jars:

  • jackrabbit-api-1.6.0.jar
  • jackrabbit-jcr-commons-1.6.0.jar
  • jackrabbit-jcr-rmi-1.5.0.jar

The tricky part is that I was unable to download them directly so I had to download jackrabbit-webapp-1.6.0.war and extract those jars from there.

Here is code that creates the viewer:

public class RabbitViewPart extends ViewPart {

  private TreeViewer viewer;
  private Session session;

  @Override
  public void createPartControl(Composite parent) {
    viewer = new TreeViewer(parent);
    viewer.setContentProvider(new JCRContentProvider());
    viewer.setLabelProvider(new JCRLabelProvider());

    try {
      Repository repository
        = new URLRemoteRepository("http://localhost:8080/rmi");
      session = repository.login(null, null);
      viewer.setInput(session.getRootNode());
    } catch (Exception e) {
      Activator.error(e);
    }
  }

  @Override
  public void dispose() {
    session.logout();
    super.dispose();
  }

  @Override
  public void setFocus() {
    viewer.getControl().setFocus();
  }
}

The code is pretty straightforward: when view part is created we connect to the Jackrabbit instance using URLRemoteRepository and open a session. First null means that we want the default workspace and the second null means that we login anonymously. Running browser looks like this:



You can download complete source code here.

Piping Output Stream to an Input Stream

Tuesday, October 20th, 2009

The Problem

Recently I had to write adapter for some API interface. Implementation was quite usual and the method of interest was void setValue(InputStream). Interface that I had to adapt exposed OutputStream write(), lucky me.

The Solution

First, exposing OutputStream is a bad idea. API client have to push data into the output stream and receiving side must consume bytes at the forced speed or provide potentially huge buffer not to block the client. The ideal solution would be to change the API to accept InputStream: such API requires minimum efforts from the client and allows implementation to extract data at appropriate rate.

So, what could I do to make it work now? Below is a simple solution that essentially collects all bytes in a buffer and then wraps it in input stream:

public OutputStream write() {
  return new ByteArrayOutputStream() {

    public void close() throws IOException {
      super.close();
      try {
        consumer.consume(new ByteArrayInputStream(buf, 0, count));
      } catch (ConsumerException ce) {
        throw new IOException(ce);
      }
    }

  };
}

You can download the complete sample here: iofun.zip.

Java Idioms for Good and Evil

Saturday, October 10th, 2009

Over time programmers learn particular tricks in their programming languages and make some habits. Here is something from my Java collection.

Good Things

Assignment Result

Assignment expression has a result, but many people ignore it. You may use it to improve the code. Consider this example:

class Controller {

  private View view;

  public void setView(View view) {
    this.view = view;
    hookView(view);
  }

  protected void hookView(View view) {...}
}

Method setView() may be written in one line:

public void setView(View view) {
    hookView(this.view = view);
}

The positive effect of this change is not only that you have to type fewer characters. Now you have to read less and so can understand the code faster.

Method Chaining

This idiom is typically used on a library basis. The author of the library that is aware of this idiom designs library API in a way that allows method chaining. In practice this means that instead of returning void you should return this. Here is a conventional code:

  Composite plate = //...
  plate.add(label);
  plate.add(text);
  plate.add(button);

If add() method returns this, and in this case it is a plate, then calls to it could be chained:

  Composite plate = //...
  plate.add(label).add(text).add(button);

The benefits are again less text to type and less code to read.

Map Literal

This is a convenient way to create a one-off map. You fill the map in static initializer:

Collections.unmodifiableMap(new HashMap() {{
  this.put("key1", "value1");
  this.put("key2", "value2");
}});

Commando Pattern

Imagine that you are writing a unit test and have to check value of some private attribute, like currentPosition in java.util.StringTokenizer. But there is no accessor so you can't do it! Here comes a reflection-based hack that penetrates private defense like commando:

StringTokenizer st = //...
Integer currentPosition = null;
try {
  Field f = st.getClass().getDeclaredField("currentPosition");
  f.setAccessible(true);
  currentPosition = (Integer) f.get(st);
} catch (NoSuchFieldException nsfe) {
} catch (IllegalAccessException iae) {
}

Bad Things

'I' In Interface Names

I believe this convention came from C++ since there was no explicit notion of interface and people have to use abstract classes. Prepending their names with 'I' was the way to reassure others that such classes are indeed interfaces. There is no need to do this in Java. Moreover, interfaces should be as clean as possible by definition since they represent API and those 'I's are just noise that makes API harder to comprehend.

So if you a young programmer and prepend 'I's then others may think that you are blindly mimic bad habits. If you are a seasoned programmer then others may think that you are just too old.

False Instanceof

The normal way to check that an object is not an instance of a class is to negate instanceof operator. Some people are frustrated that negation has a higher priority and they have to use parenthesis:

if (!(obj instanceof String)) {
  // ...
}

So they write this check like this:

if (false == obj instanceof String) {
  // ...
}

The problem is not only that it's longer now but it's harder to read. The normal version reads like 'if not obj instance of string' and is close to english prose while the second version is quite far from it.

The counter argument is that the second version is easier to type: you don't have to press Shift key. It is true, but typically we write code once and read it several times later so I would prefer more readable version.