Recently I had to roll out a REST-Webservice on Glassfish which used jMagick as a library. Now, ImageMagick is a C++ library and is available in Java through JNI. The installation on a standard EC2-Ubuntu AMI is pretty straightforward once you know the tricks. I executed the following steps to get things up and running:
  1. Make an EC2-Instance, attach an EBS and install JDK7 and GFv3.2.1 (these are the version which I installed)
     
  2. Install ImageMagick using sudo yum install ImageMagick. You can’t use apt-get or aptitude since Amazon prefers yum.
     
  3. Next thing is to install jMagick. You can download the latest from ftp://ftp.imagemagick.org/pub/ImageMagick/java/. Use wget to get the RPM (32 or 64 bit – I used the 64bit version).
    wget ftp://ftp.imagemagick.org/pub/ImageMagick/java/jmagick-6.4.0-3.x86_64.rpm
  4. Install the RPM using sudo yum  jmagick-6.4.0-3.x86_64.rpm
     
  5. When all goes well, you should be able to see a handful of Magick-files using ls /usr/lib64/libM* (which were installed in step 2) and of course the Java library ls /usr/lib64/libJMagick.so
  6. There should also be an accompagning JAR file for the library. Check if /usr/lib64/jmagick-6.4.0.jar is there.
     
  7. Now we get to the Glassfish part. Suppose your domain is called “domain1”. Copy the JAR into the /lib directory of your domain so it will get loaded during the startup of Glassfish.
     
  8. Point your browser to the admin-console or open the domain.xml. You need to add a JVM-parameter to get this running. In the console go to the configurations / server-config / JVM-settings and then the JVM-options tab and add the following line:

    -Djmagick.systemclassloader=no

    or add in the domain.xml the line

    -Djmagick.systemclassloader=no
    This line prevents jMagick of using the system-class-loader as you might have expected. Not adding this line leads to errors.
     

  9. Restart your domain and deploy the application. The System.loadLibrary(“JMagick”); in Magick.java runs as planned. (http://jmagick.svn.sourceforge.net/viewvc/jmagick/trunk/src/magick/Magick.java?revision=91&view=markup
We can now redeploy our application in Glassfish at will because the class is loaded by Glassfish during the startup. When not, you can expect exception when redeployen when your jMagick.JAR is in your project. The classloader will tell you that the classes are already loaded when you deploy a second time.
PS: when running Maven tests outside the container, do not forget to specifiy the -Djava.library.path=/your-path-to/libJMagick.so. 
PS2: if you install JMagick using a repository, then the JMagick.so files are stored in the /usr/lib64/jni directory. Copy the libJMagick.so file to /usr/lib64 and restart your domain. There is no need to add java.library.path to the JVM parameters in the domain.xml (something which apparently doesn’t function well).

Copying symlinks

Posted: April 15, 2013 in NIO, Symlinks

JDK7 offers a whole new set of methods to work with symbolic links. This was in pre-JDK7 times pretty difficult and often you had to execute barebone copy statements through the runtime. There is one method which I missed in the API. You can open or follow the link, or test whether your file is a link, but you cannot “copy” the link itself. You need to resolve the original link and create a new link as illustrated in the class below.

The class could surely be optimized, but it gives you an idea on how the symbolic links function.

public class LinkFileVisitor extends SimpleFileVisitor<Path> {

    private Path fromPath;

    private Path toPath;

    public LinkFileVisitor(final Path fromPath, final Path toPath) {
        this.fromPath = fromPath;
        this.toPath = toPath;
    }

  public static void copy(final Path from, final Path to)
            throws IOException {

        // make sure it is a directory
        if (!Files.isDirectory(from)) {
            throw new IllegalArgumentException(
                    String.format("%s is not a directory", from.toString()));
        }

        Files.walkFileTree(from, new HashSet(),
                Integer.MAX_VALUE, new LinkFileVisitor(from, to));

    }

    @Override
    public FileVisitResult preVisitDirectory(final Path dir,
            final BasicFileAttributes attrs)
            throws IOException {
        Path targetPath = toPath.resolve(fromPath.relativize(dir));
        if (!Files.exists(targetPath)) {
            Files.createDirectory(targetPath);
        }
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
            throws IOException {
         if (Files.isSymbolicLink(file)) {
            Path link = toPath.resolve(fromPath.relativize(file));
            if (Files.exists(link, LinkOption.NOFOLLOW_LINKS)) {
                Files.delete(link);
            }
            Files.createSymbolicLink(link, Files.readSymbolicLink(file));
        } else {
            Files.copy(file, toPath.resolve(fromPath.relativize(file)),
                    StandardCopyOption.REPLACE_EXISTING);
        }
        return FileVisitResult.CONTINUE;
    }
}

Well, as you might have expected from the title, the answer is “yeah well, not really”. A singleton in the J2EE world is not a singleton as you know it from the normal Java world. In a non-J2EE environment you typically write something like this to generate a singleton:

public class MySingleton {
  final private static MySingleton instance = new MySingleton();

  protected String name = "whatever";

  private MySingleton() {}

  public static MySingleton instance() {
    return instance;
  }
}

You can get exactly one instance of this bean and you could access the fields directly or through getter and setters. There is only one instance of this object and all information is stored there. This pattern is well known to every programmer. The demand was great to port this pattern to the J2EE world. A new type of bean was invented, the Singleton bean. The idea behind all this is to provide a single instance of a particular bean within your application. You can construct a singleton bean with the following code:

@LocalBean
@Singleton
@Startup
public class MySingleton {

}

First we declare it as a local bean, and we load it during startup. The @Singleton annotation makes a singleton out of this class. But is this class really instantiated once when using the @LocalBean annotation? No, it is instantiated twice! Let’s test this out with by adding a static field in the bean.

static int i=1;</pre>
public MySingleton() {
    System.out.println("INSTANCE: " + i++);
}

You will see in the logs that you get two different instances. If you print out the reference of the class, you will notice that one of the instances is a proxy object. The proxy object is instantiated too and the constructor is instantiated again. When you write some kind of initialisation logic inside the constructor, you will run into somekind of unwanted behaviour because it executes your code twice where you expect that the constructor is executed only once. So, don’t use the constructor to set up your data but use the @PostConstruct annotation to execute a method with your initialisation logic in it.

@PostConstruct
public void init() {
   ... do your init here ....
}

You will see that the proxy object does not execute this code (which is obvious of course because the code is not in the constructor anymore). Another pitfall might be that during some kind of rapid prototyping action you store some state-data in a non-private field in the singleton or a stateful session bean. When you do not provide a getter/setter for the field, the field-value of the injected bean will always be null because the proxy gets injected and not the “real” instance. The proxy object does not store state. Let’s test this:

@LocalBean
@Singleton
@Startup
public class MySingleton {
    protected String name = "whatever";
    .....
    public String getName() {
         return this.name;
    }
}

We inject this bean in another session:

@LocalBean
@Stateless
public class MyTest {
    @EJB private MySingleton mySingleton;

    public void test() {
        // mySingleton.name --&gt; null; (proxy)
        // mySingleton.getName() ---&gt; "whatever" (real object)
    }
}

The injected reference is the proxy object without state. Getting the value of the field directly must always return null when it is not initialised. The real state is maintained in the singleton. You can get the “real” data when you use the method “getName()” because the proxy object tunnels your method and not the field. This is the reason behind the fact that you may not use fields directly in session-beans.

Well, as you might have expected, it is really a bad idea to get the field from a singleton or other bean directly (in general, it is an anti-pattern in J2EE). Try to encapsulate your data with nice getters and setters and keep in mind that your objects can get dynamic proxies depending on the annotations you add to the class.