Saturday, 23 May 2009

Implementing Aspect Oriented Programming by Hacking Java Class Files Programmatically

This is an Apache-licensed Java library for manipulation of .class files which can be useful when hacking together aspect-oriented extensions to Java. The Apache license allows you to use BCEL for commerical projects. The heart of BCEL is the JavaClass class, which represents a Java class in memory. A ConstantPool class represents the constant pool. BCEL supports something called load-time reflection, whereby these classes all become useful. I'll keep coming back to this point, because it is something that goes beyond the scope of the Reflection API. It can be used to fundamentally change the behaviour of Java classes.
  • BCEL supports load-time reflection. Run-time reflection is built into Java via the Reflection API, load-time reflection allows you to modify the bytecode instruction set at the time of loading the class. How does this differ from a custom classloader? Well, you still need to write a custom class loader, which instead of passing bytecode directly to JVM, first passes it through your run-time system using BCEL API.
  • It has a Static API to map structures described in the JVM specification. It also has a Generic API to create and transform class files dynamically, its heart is the ClassGen class, which allows you to create new class files, and add methods and attributes dynamically.
  • Comes with a bytecode verifier called JustIce.
  • Comes with a Class2HTML utility to generate html bytecode documentation for classfiles. This is interesting to see e.g. how synchronized code is implemented at the bytecode level.

So, if you want to write some bytecode manipulation programs, don't do it from scratch, but use BCEL as a basis!

Friday, 22 May 2009

Java versus C++ Benchmarks

Here is an old, University of Southern California, study done on relative performance between Java and C++.

There are some academic reasons why Java may be faster than C++, in some situations.

Thursday, 21 May 2009

How real-time is javax.realtime?

The Java real-time specification - at last! Real-time brought to Java. But how real-time is real-time? How is the garbage collector tamed?

Hype warning: "javax.realtime (pronounced JARVAX-DOT-REALTIME) ...the one, the ONLY incredible javax base package you will need for all your real time Java needs!"

Let us try to prove or disprove the HYPE-othesis.

The class RealtimeThread extends Thread and adds various real-time services. The thread can be created using a SchedulingParameters object. NoHeapRealtimeThread is a specialization of RealtimeThread.

An instance of NoHeapRealtimeThread (NHRTT) may immediately preempt any implemented garbage collector, logic in its run() is NEVER allowed to allocate or reference any object allocated in the heap. Byte-code-wise, it is illegal for a reference to a heap-alloc'ed object to manifest in the operand stack for the NHRTT.

The JamaicaVM is an implementation of RTSJ. It provides hard real-time guarantees for all primitive Java operations, as well as hard realtime garbage collector. It runs on Linux, Windows and Solaris and various OS's including VxWorks.

Wednesday, 20 May 2009

Centering a JFrame

The old way to center a JFrame was to use the default java.awt.Toolkit object and call getScreenSize then explicitly call setLocation on the JFrame.


Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int x = frame.getSize().width;
int y = frame.getSize().height;


Since 1.4 the better way is to call setLocationRelativeTo(null). This will center the JFrame. If you supply a Component object to the function, and the component is say on the left side of the screen, your JFrame will appear to the right of the screen.

Monday, 18 May 2009

An Alternative to IBM Codecs

FOBS, the open source king of codecs.

Sunday, 10 May 2009

Creating Executable Jar Files

Java 1.2 brought with it the ability to create executable jar files. You can do this from eclipse using "Jar Export" wizard.

The Essence of Static Initializers

SIB Explained

If you write a "static" Java class, by which I mean a class containing only static methods and static data, you may need a static initializer block (SIB) to initialize some of the private data (for example, java.util.HashMap that stores some mappings).

SIB is used to init static variables when the class is loaded. It resembles a method with no name, no arguments and no return type (not allowed to contain a return statement).

It is executed by VM when class is loaded. An alternative to SIBs is to write a private static method to perform initialization.

Problems in Static Initializers

An exception inside a static initializer will result in an ExceptionInInitializerError (which is a java.lang.LinkageError). One solution is to catch the exception inside the SIB and handle appropriately. This error may happen if initialise a data structure statically (after the SIB block). In this case, the data structure may not exist if accessed from within the SIB block.

Java Packages

To create a package, put a package statement at the top of each source file containing the package types. This statement must be the first line in each source file.

Without the package statement, types end up in unnamed packages. This is acceptable only for small or temporary applications when you are just beginning the development process.

Package names tend to:
1. be written in lowercase
2. use reversed internet domain convention

Thursday, 7 May 2009

What is the size of Eden?

What should the size of Eden be? Is 128mb sufficient?
What is the difference between a minor and major collection?

In Java memory is managed in generations, which are memory pools for holding objects of different ages.

GC occurs in each generation when it fills up.

Objects are ALLOCATED in Eden, and most objects die there. When Eden fills up, a minor collection occurs, during which some objects move to an older generation. When older objects need to be collected, a major collection occurs (this is often slower since it involves all living objects).

Saturday, 2 May 2009

Running a Java Program from the Command Line: NCDF "Exception"

This is the most rudimentary task every Java newbie struggles with (and may take hours to resolve!) This post will aim to delve into the knowledge needed to succeed in this simple task, which requires a surprising amount of knowledge.

Having written (and compiled) a simple Java program how do we run it from the command-line? How many times has one tried:

java classname

only to be greeted by the all-too-familiar java.lang.NoClassDefFoundError. In an enterprise environment this error is almost never seen, since virtually every company running a large Java infrastructure implements a run script to solve all the

* issues of classpath
* package names/relative paths (the tight coupling between directory names and package names is a particular source of initial frustration and bewilderment when running Java programs for the first time).

This contrasts heavily with the relative simplicity of compiling and running C programs.

Java programs, as we know are compiled into class files. Suppose I have written a Java game called DinoGame that is compiled into DinoGame.class, which is stored in a directory called dinosaurs. To view contents of the DinoGame class, I do the following:

* cd dinosaurs
* javap DinoGame (NOT javap DinoGame.class)

This will tell me: "O i've been compiled from DinoGame.java and here are my methods". One of my methods is public static void main which takes java.lang.String[] (1-d array) i.e. the output of javap will always display fully-qualified package names.

Now I try running DinoGame by typing: java DinoGame from the dinosaurs directory. Oh dear! java.lang.NoClassDefFoundError: Could the find the main class: DinoGame. Program will exit. However!! java provides us with a useful hint (wrong name: dinosaurs/DinoGame). The java interpreter sees the class file in the current directory but it won't be able to execute it because it has the wrong name.

* cd out of the dinosaurs directory
* java -classpath . dinosaurs/DinoGame OR java -cp . dinosaurs.DinoGame (again NOT dinosaurs.DinoGame.class)

The -classpath . (or -cp .) is needed here since there are no class files in the current directory, so there are no reference points for the Java interpreter to use in generating useful error messages. To infer a problem such as the lack of a fully qualified classname would require the Java interpreter (run from a specific directory) to recursively search all subdirectories from the current directory which
could be very inefficient.

The tricky thing here is you need to think in terms of fully qualified package names. As we have seen from javap output, this is what the interpreter uses to refer to class files.

Now even if you get the above sequence correct (java -cp . class-with-fully-qualified-package-name), if you have a broken java.exe process running in the background (at least in Windows environment) whatever sequence of characters you type may not work and still crash with NCDF Exception (ok, ok I know it's written as NoClassDefFound ERROR, but what triggers it is the java.lang.ClassNotFound EXCEPTION, so for conciseness let's refer to it as NCDF EXCEPTION, since an exception is the underlying generator of this error).

Another useful point to remember is whenever you see a .java or .class file, remember that the Java toolset invariably requires you to OMIT the .java or .class extension when using your Java files as arguments to the tools (read the code in openJDK to see how many times String.concat(".class") appears! Forgetting this simple rule will result in frustration!

It is worth delving a little into the rather ungainly stack trace that appears when you get an NCDF error. It gives some insight into the core packages of Java (not just java.lang). It shows a tight interplay between java.security and java.net packages.

NCDF error is generated by CNF exception which is generated by java.net.URLClassLoader$1.run(Unknown source). The java.net.UCL will provide a starting point for some interesting analysis.

java.net.UCL (see source)is implemented by David Connelly (around 600 lines of code, well-worth reading, every single line provides essential knowledge) was introduced in Java 2 and implements the generified findClass method (generified in the sense it returns a Class object of wildcarded type); as a contextual note, remember generics were only introduced in Java 5. UCL.findClass is the fella that winds up throwing the "class not found" exception. It is effectively one call into native code: AccessController.doPriviliged(privileged action, created as an anonymous class).

This stream of events begins with java.lang.ClassLoader. method loadClassInternal (a synchronized method invoked by the virtual machine to load a class) which calls auxiliary methods loadClass(String name)->loadClass(String name, bool resolve) (classes must be resolved before they can be used). What does it mean to resolve a class, I hear you ask? Read the "Execution" chapter of the Java Language Specification. Resolution involves resolving symbolic references to other classes by loading thoses classes and checking the references are valid. Resolution is optional at the time of initial linkage.

Footnote:
Java security comprises a very large set of APIs and if you want a lowdown your best bet is right here).