« February 2006 »
SunMonTueWedThuFriSat
   
1
2
3
5
6
7
8
9
10
11
12
16
17
18
19
20
21
23
25
26
27
29
30
31
 
       
Today
XML

Blog::Navigation

GetJava Download Button
Get the Source
Personal Blog

Blog::Referers

Today's Page Hits: 769

Powered by Roller Weblogger.
« Previous month (Jan 2006) | Main | Next month (Mar 2006) »
20060328 Tuesday March 28, 2006

India wins a low scoring one day match!

India made 203. England all out for 164!. I really don't know what to say about this match... I like that 434/438 match better!!



( Mar 28 2006, 04:24:01 PM IST ) Permalink Comments [1] del.icio.us | furl | simpy | slashdot | technorati | digg

20060324 Friday March 24, 2006

Scripting for the Java Platform

I've just read Language wars are so boring and from there went to read Scripting flamewar. Some thoughts on scripting in Java "context"....

For scripting languages for the Java platform - assuming the language allows access to Java classes, then in effect the "primitives" space of the language becomes the entire JDK - the endless primitive extension problem is left to the JDK. For example, JavaScript engine in JRE (included in Mustang) lives in the "context" of Java - Java classes can be accessed and Java interfaces can be implemented in script.

Some of the performance issues around scripting may possibly be addressed by "compiling" scripts to bytecode on-the-fly (a sort of first level "hotspot" for scripts?). That is where invokedynamic or any other possible improvements from JSR 292 could help. The typing/non-typing "dichotomy" may possibly be addressed by pluggable types.



( Mar 24 2006, 07:46:23 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060322 Wednesday March 22, 2006

Another Indian collapse!!

Like many in India, I do like (that is an understatement!) cricket. All too familiar, yet another Indian team seconding innings collapse today :-(. But, I think England deserved to win this match.

I think Indian bowlers did their job reasonably well. It is time for Indian batsmen to play against Munaf Patel and get trained against the bouncers?



( Mar 22 2006, 02:26:56 PM IST ) Permalink Comments [3] del.icio.us | furl | simpy | slashdot | technorati | digg

20060315 Wednesday March 15, 2006

Understanding Java class loading - part 2

Understanding Java class loading - part 2

This is continuation of my earlier post.

Recap

Notation

At runtime, a Java class is uniquely identified by the pair: fully qualifed name and defining loader instance. We denote a class by


    <qualified-class-name, defining-loader>    

Examples:

    <java.lang.Object, null>
    <com.acme.MyAppClass, sun.misc.Launcher$AppClassLoader@768812>

When JVM uses a loader Li as initiating loader to load class C, we denote it by

    CLi

With both initiating loader Li and defining loader Ld, we denote

    <C, Ld>Li

Examples:

    <java.awt.Frame, null>sun.misc.Launcher$AppClassLoader@768812&
    <com.acme.AppUtil, sun.misc.Launcher$AppClassLoader@768812>sun.misc.Launcher$AppClassLoader@768812&

First one denotes the class with name "java.awt.Frame" defined by null (bootstrap loader). JVM initiated loading using the application class loader. Second one denotes the class with the name "com.acme.AppUtil" defined by application class loader and JVM initiated loading using the application loader itself.

Loader constraints

There are two ways in which a Java class "A" refers to another Java class "B".
  1. class A reads/writes a field of class B
  2. class A calls a method of class B
Consider that A refers to B's field "f". And assume field "f" is of reference type "T".

class A {
    void func(B b) {
        T t =  b.f;
        // operate on "t"
    }
}

class B {
    public T f;
}


During compilation, javac verifies that B has a field "f" of same type "T" (or subtype of "T"). Here, "same type" during compilation just means the same fully qualified class name. At runtime, if both A and B are loaded (i.e, defined) by the same class loader, say L, then we have no problem. JVM would use the same class loader "L" as initiating loader to load "T" - the field type. In other words, both class <A, L> and and class <B, L> would have same notion of type "T".

But, what if A and B are loaded (defined) by different loaders? Let us assume <A, L1> and <B, L2> and L1 != L2. In this case, to resolve type "T" from <A, L1>, JVM will use L1 as initiating loader. To resolve type "T" from <B, L2>, JVM will use L2 as initiating loader. Unless care is taken, these two loadClass calls could result in two different classes -- and hence assumption of type equality made during compilation would break! One quick and dirty solution would be this: whenever field is resolved at runtime force class loading for "T" by both L1 and L2 and check equality. But, that means we are leaving lazy loading behind - we are forcing early loading!

Instead of this solution, JVM takes another solution: impose loader constraints.

Now consider case (2) above. Class "A" refers to a method of class "B". Let us say A refers to the method of the following form


   class B {
       R foo(A1 a1, A2 a2,... An an);
   }

   class A {
      void func(B b) {
         b.foo(/* args here */);
      }
   }



and assume that all Ai=1, n are reference types and R (return type) is also a reference type. Again, during compilation javac would have verified that method "foo" of correct signature exists in class "B". Now again assume class A and B are defined two different loaders L1, L2. While linking this method "foo", JVM would impose the following loader constraints:

Again these constraints are not verified immediately. These are just recorded in an internal data structure. JVM would verify these constraints at subsequent class load attempts.

There is one more case we have ignored so far: class B extends A and overrides method "foo". Again, overriding method B.foo is subsitutable everywhere A.foo can be called (the subtype subsititution).

   class A {
       R foo(A1 a1, A2 a2... An an) {}
   }

   class B extends A {
       @Override R foo(A1 a1, A2 a2... An an) {}
   }

If A and B are defined by two different loaders L1 and L2, then JVM imposes the following loader constraints at the time of preparation of B. As mentioned above, these constraints are just recorded initially and at each subsequent class load these would be verified.

Case Study

If all of the above sounds too abstract to you, then let us consider a concrete problem - a bug we faced in a web container. Webcontainers support "application reloading" without restarting of the webserver. A webcontainer used classloaders for application reloading. The container used a different class loader to reload an application. For example, if one of .jsp files of the webapp is modified (detected by filesystem timestamp), then the webcontainer would recompile that particular .jsp and reload the app using a different class loader instance. So far so good - everything worked as expected. But then, someone thought it may not be optimal to load all classes of the webapp just because one particular class - the class corresponding to the modifed jsp - changed. So, he optimized by the following change:

This way, he achieved "sharing" of all other unmodified classes of the webapp. Again, everything looked right. Then, someone modified a .jsp file with the following code:

 <!-- foo.jsp file fragment -- >

 <--newly added part of JSP -->
 <%!
    class Util {
      public void func() {}
    }
 %>

 <%!Util u = new Util();%>


Then, he attempted to "reload" the webapp! He hit the infamous "loader constraint violation" at the line where "new Util()" is executed! Why? The JSP file is compiled as a Servlet class, say "FooServlet.class". And his "Util" class became inner class of FooServlet. javac passes outer instance to inner class constructor. This is how instance variables of outer class are made accessible from inner class instance.

One particular fix for this problem (ugly workaround?) would be to force L2 - the new loader - to load (define) all inner, nested, anonymous classes of FooServlet class and delegate loading of all other classes to the parent loader!!

References



( Mar 15 2006, 06:59:09 PM IST ) Permalink Comments [6] del.icio.us | furl | simpy | slashdot | technorati | digg

20060314 Tuesday March 14, 2006

DTrace: Java method signatures in jstack() output

There are many improvements in Mustang (Java SE 6)'s DTrace support. A recent improvement: Starting from Mustang build 75, DTrace jstack() action prints Java stack trace with method signatures. Because Java methods are overloaded by argument types, it is very useful to view method signatures as part of stack trace output. With this change, the stack trace would look like:


              pollsys:entry
              libc.so.1`__pollsys+0x4
              libc.so.1`poll+0x7c
              libjvm.so`__1cIos_sleep6Fxb_i_+0xa28
              libjvm.so`__1cCosFsleep6FpnGThread_xb_i_+0x1f0
              libjvm.so`JVM_Sleep+0x518
              java/lang/Thread.sleep(J)V
              java/lang/Thread.sleep(J)V
              t.main([Ljava/lang/String;)V
             [....]

instead of this:

              pollsys:entry
              libc.so.1`__pollsys+0x4
              libc.so.1`poll+0x7c
              libjvm.so`__1cIos_sleep6Fxb_i_+0x8d4
              libjvm.so`__1cCosFsleep6FpnGThread_xb_i_+0x204
              libjvm.so`JVM_Sleep+0x534
              java/lang/Thread.sleep
              java/lang/Thread.sleep
              t.main
              [....]



( Mar 14 2006, 05:18:42 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060313 Monday March 13, 2006

Understanding Java class loading

Understanding Java class loading

Are you thinking of writing ClassLoaders? or are you facing "unexpected" ClassCastException or LinkageError with wierd message "loader constraint violation". Then, it is time to take a closer look at Java class loading process.

What is a ClassLoader and how it loads?

A Java class is loaded by an instance of java.lang.ClassLoader class. java.lang.ClassLoader itself is an abstract class and so a class loader can only an instance of a concrete subclass of java.lang.ClassLoader. If this is the case, which class loader loads java.lang.ClassLoader class itself? (classic "who will load the loader" bootstrap issue). It turns out that there is a bootstrap class loader built into the JVM. The bootstrap loader loads java.lang.ClassLoader and many other Java platform classes.

To load a specific Java class, say for example com.acme.Foo, JVM invokes loadClass method of a java.lang.ClassLoader (actually, JVM looks for loadClassInternal method - if found it uses that method, or else JVM uses loadClass. And loadClassInternal method calls loadClass). loadClass receives name of the class to load and returns java.lang.Class instance that represent the loaded class. Actually, loadClass method finds the actual bytes of .class file (or URL) and calls defineClass method to construct java.lang.Class out of the byte array. Loader on which loadClass is called is referred as initiating loader (i.e., JVM initiates loading using that loader). But, the initiating loader need not directly find the byte[] for class - instead it may delegate the class loading to another class loader (for example, to it's parent loader) - which itself may delegate to another loader and so on. Eventually some class loader object in delegation chain ends up calling defineClass method to actually load the concerned class (com.acme.Foo). That particular loader is called defining loader of com.acme.Foo. At runtime, a Java class is uniquely identified by the pair - the fully qualified name of the class and the defining loader that loaded it. If the same named (i.e., same fully qualified name) class is defined by two different loaders, these classes are different - even if the .class bytes are same and loaded from the same location (URL).

How many classloaders and where they do load from?

Even with a good old simple "hello world" Java program, there are atleast 3 class loaders.

  1. bootstrap loader
    • loads platform classes (such as java.lang.Object, java.lang.Thread etc)
    • loads classes from rt.jar ($JRE_HOME/lib/rt.jar)
    • -Xbootclasspath may be used to alter the boot class path -Xbootclasspath/p: and -Xbootclasspath/a: may be used to prepend/append additional bootstrap directories - have extreme caution doing so. In most scenarios, you want to avoid playing with boot class path.
    • In Sun's implementation, the read-only System property sun.boot.class.path is set to point to the boot class path.Note that you can not change this property at runtime - if you change the value that won't be effective.
    • This loader is represented by Java null. i.e., For example, java.lang.Object.class.getClassLoader() would return null (and so for other bootstrap classes such as java.lang.Integer, java.awt.Frame, java.sql.DriverManager etc.)
  2. extension class loader
    • loads classes from installed optional packages
    • loads classes from jar files under $JRE_HOME/lib/ext directory
    • System property java.ext.dirs may be set to change the extension directories using -Djava.ext.dirs command line option.
    • In Sun's implementation, this is an instance of sun.misc.Launcher$ExtClassLoader (actually it is an inner class of sun.misc.Launcher class).
    • Programmatically, you can read (only-read!) System property java.ext.dirs to find which directories are used as extension directories. Note that you can not change this property at runtime - if you change the value that won't be effective.
  3. application class loader
    • Loads classes from application classpath
    • Application classpath is set using
      • Environment variable CLASSPATH (or)
      • -cp or -classpath option with Java launcher
      If both CLASSPATH and -cp are missing, "." (current directory) is used.
    • The read-only System property java.class.path has the value of application class path. Note that you can not change this property at runtime - if you change the value that won't be effective.
    • java.lang.ClassLoader.getSystemClassLoader() returns this loader
    • This loader is also (confusingly) called as "system class loader" - not to be confused with bootstrap loader which loads Java "system" classes.
    • This is the loader that loads your Java application's "main" class (class with main method in it). In Sun's implementation, this is an instance of sun.misc.Launcher$AppClassLoader (actually it is an inner class of sun.misc.Launcher class).
    • The default application loader uses extension loader as it's parent loader.
    • You can change the application class loader by command line option -Djava.system.class.loader. This value specifies name of a subclass of java.lang.ClassLoader class. First the default application loader loads the named class (and so this class has to be in CLASSPATH or -cp) and creates an instance of it. The newly created loader is used to load application main class.

Typical class loading flow

Let us assume you are running a "hello world" java program. We will how class loading proceeds. JVM loads main class using the "application class loader". If you run the following program


class Main {
	public static void main(String[] args) {
            System.out.println(Main.class.getClassLoader());
            javax.swing.JFrame f = new javax.swing.JFrame();
            f.setVisible(true);

            SomeAppClass s = new SomeAppClass();
	}
}

it prints something like
sun.misc.Launcher$AppClassLoader@17943a4

Whenever a reference to some other class has to be resolved from Main class, then JVM uses the defining loader of Main class - the application class loader - as initiating loader. In the above example, to load the class javax.swing.JFrame, JVM will use the application class loader as initiating loader. i.e., JVM will call loadClass() (loadClassInternal) on the application class loader. The application class loader delegates that to extension class loader. And the extension class loader checks whether it is a bootstrap class (using a private method - ClassLoader.findBootstrapClass) and the bootstrap loader defines the class by loading it from rt.jar. When reference to SomeAppClass has to be resolved, JVM follows the same process - it uses application class loader as initiating loader for it. The application loader delegates it to extension loader. Extension loader checks with bootstrap loader. Bootstrap loader won't find "SomeAppClass". Then extension loader checks whether "SomeAppClass" is in any of the extension jars and it won't find any. Then application class loader check the .class bytes in application CLASSPATH. If it finds, it defines the same. If not, NoClassDefFoundError will be thrown.

Summary

Stay tuned for more discussion on loader constraints and LinkageErrors..

To be continued...



( Mar 13 2006, 09:30:58 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060304 Saturday March 04, 2006

Java "class"-ic errors

Few errors are so common (Frequently Faced Errors or FFEs?) - asked many times in forums, email lists (internal/external) - and it is frustating to face one of these "starting problems". I am talking about the classloading errors with Java. I'll try to list few common errors and most probable reasons.

When you are out of starting troubles, you may still face other classloading issues. "unexpected" class is loaded etc. How can you debug that?



( Mar 04 2006, 08:12:18 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

Copyright (C) 2005, A. Sundararajan's Weblog