Showing posts with label OpenJDK. Show all posts
Showing posts with label OpenJDK. Show all posts

Monday, March 03, 2008

Listing Java Process from Java

Month Ago, one of my colleagues was making an application, actually the UI flavor of JStack. Since JStack asks you the process ID for attaching the particular Java Application with JStack. In a UI based tool, telling user to do Alt-Ctrl-Del and see the process ID,not sounds good. So, my first impression was that you have to show the java process in the drop down and user will select in that. Some day back even, I want to find all process running on my machine from java code for some stupid purpose. I am trying to write some code for both of them. Java can't play with system process and hence invoking a runtime is only solution to get all process and here it is:


import java.io.*;
class ListProcess {
public static void main(String[] args)throws IOException
{
Runtime runtime = Runtime.getRuntime();
String cmds[] = {"cmd", "/c", "tasklist"};
Process proc = runtime.exec(cmds);
InputStream inputstream = proc.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String line;
while ((line = bufferedreader.readLine()) != null) {
System.out.println(line);
}
}
}


Code is written exclusively for Windows Machine :). And one line change in this code will list you only java running process.

String cmds[] = {"cmd", "/c", "jps"}; this is nothing but running jps.exe file in bin (jdk6 onwards). Its not all done. Writing Runtime code is not the real solution as there is little of platform dependencies. So, I have decide to write the code for getting List of Java Process. Again, I have checked by OpenJDK code for jps(search on jps.java file :) ) and I got some hint how to do it and here it goes:

import java.util.*;
import sun.jvmstat.monitor.*;

public class ListJavaProcess {
public static void main(String[] args) throws Exception {

/* Checking for local Host, one can do for remote machine as well */
MonitoredHost local = MonitoredHost.getMonitoredHost("localhost");
/* Take all active VM's on Host, LocalHost here */
Set ids = new HashSet(local.activeVms());
for (Object id : ids) {
/* 1234 - Specifies the Java Virtual Machine identified by lvmid 1234 on an unnamed host.
This string is transformed into the absolute form //1234, which must be resolved against
a HostIdentifier. */
MonitoredVm vm = local.getMonitoredVm(new VmIdentifier("//" + id));
/* take care of class file and jar file both */
String processname = MonitoredVmUtil.mainClass(vm, true);
System.out.println(id + " ------> " + processname);
}
}
}


I have written good amount of comment as it is all together a sun import rather than java or javax import(so no javadoc). This import resides in tools.jar, so even running simple javac and java will not work. So, running the program will go here:


E:\Program Files\Java\jdk1.6.0_10\bin>javac -classpath "E:\Program Files\Java\jd
k1.6.0_10\lib\tools.jar" ListJavaProcess.java


E:\Program Files\Java\jdk1.6.0_10\bin>java -classpath .;"E:\Program Files\Java\j
dk1.6.0_10\lib\tools.jar" Vista

3700 ------> ListJavaProcess

Right now only one java process is running. Now in the second code, you can play with some of the java process, but with native process in the above code you can't do anything except watching it :)

Saturday, February 09, 2008

Sorting with Different Locale

Sorting is always a tricky game in any language. Language like Java has its own high class sorting API's. But have you ever think, how sorting works in different locales ? How it work in French or in Spanish? Lets have a look...

This is my String Array which I want to sort:
String[] names = {"fácil", "facil", "fast","Où", "êtes-vous", "spécifique", "specific", "ou"};
It contains words of French Locale(some of my fav. words like Où :-) )
And here goes our typical sorting program:

String[] names = {"fácil", "facil", "fast","Où", "êtes-vous", "spécifique", "specific", "ou"};
List list = Arrays.asList(names);
Collections.sort(list);
Iterator itr = list.iterator();
while(itr.hasNext()) {
System.out.print(itr.next()+ " ");
}

And the result:
Où facil fast fácil ou specific spécifique êtes-vous

Result can surprise you and can make your French friend angry :-) because he never want "fast" should come before "fácil", just because there is one special 'á' (sorting is true according to UNICODE sequence but not according to locale)

To face this problem JDK comes with something called Collator (I guess in 1.4 onwards) which take care of locale while sorting.
Collator is an abstract class. You can look the source code at location in Openjdk: jdk\src\share\classes\java\text\Collator.java. Highly documented file.

Collator has some flavors like PRIMARY, SECONDARY, TERTIARY, IDENTICAL which all tells what need to take care while sorting. Please read the javadoc for detail.

Now here is my simple code:

import java.text.*;
import java.util.*;


class CollatorTest {

public static void main(String[] args) {
String[] names = {"fácil", "facil", "fast","Où", "êtes-vous", "spécifique", "specific", "ou"};
List list = Arrays.asList(names);
Collections.sort(list);
Iterator itr = list.iterator();
while(itr.hasNext()) {
System.out.print(itr.next()+ " ");
}

Locale[] loc = Collator.getAvailableLocales();

/* for(int i=0;
&<
{
System.out.println(loc[i].getDisplayName());
}
*/
Collator myCollator = Collator.getInstance(new Locale("fr"));
myCollator.setStrength(Collator.PRIMARY);
Collections.sort(list, myCollator);
itr = list.iterator();
System.out.println("");
while(itr.hasNext()) {
System.out.print(itr.next() + " ");
}

myCollator.setStrength(Collator.TERTIARY);
Collections.sort(list, myCollator);
itr = list.iterator();
System.out.println("");
while(itr.hasNext()) {
System.out.print(itr.next() + " ");
}
}
}

And here is the result:
Où facil fast fácil ou specific spécifique êtes-vous
êtes-vous facil fácil fast Où ou specific spécifique
êtes-vous facil fácil fast ou Où specific spécifique

First one is the normal sorting, second and third is Collator sorting with 2 different types. You can very easily see that we are giving respect to other locale as well in sorting. There are 2-3 line comments in the code, which will tell which all locale Collator is supporting.

Wednesday, January 02, 2008

MyClassLoader - Java ClassLoader - Part 2

MyClassLoader will take one more entry for completion. Before writing our own custom ClassLoader, we have to devote sometime to see the methods of ClassLoader. Some of them need special attention while others we can ignore. Before starting with methods, we can see some type of ClassLoader available in jdk(openjdk) itself. AppletClassLoader, RMIClassLoader, SecureClassLoader, URLClassLoader are some of them. Remember all the custom ClassLoader need to extend ClassLoader except one :-). Any guesses ? Bootstrap Class Loader - Yes, this is responsible for loading runtime classes(rt.jar- very famous jar file in /jre/lib :-) ) . It has a native implementation and hence varies across JVM. So, when we write

java MyProgram

Bootstrap ClassLoader comes into the action first.

Alright, back to methods: we can see the whole list of methods of ClassLoader here. But we will see those of our interest:

- loadClass -> entry point for ClassLoader. In JDK 1.1 or earlier, this is the only method we need to override but after JDK 1.2 some dynamics get changed. Will discuss that later.

- defineClass -> As I mentioned in the last blog, this is one of the complex method which takes raw data and turn it into Class Object. Need not to worry, it is defined as final(so we can't change... who want to change).

- findSystemClass -> looks for the class file in local disk, if yes calls defineClass and convert the raw data into Class Object.

In JDK 1.2, new delegation model came into picture where if ClassLoader can't able to find a class, it asks (it's) parent ClassLoader to do it. JDK 1.2 came up with a new method called findClass which contains specialized code and help you when you are messed up with lot of ClassLoader. So, from JDK 1.2 and onwards, we just need to override findClass and everything will work fine, if not it will throw ClassNotFoundException. There are lot of other methods like getParent, getSystemClassLoader, but we can write our custom ClassLoader without touching these methods.

So, top skeleton looks like:

public class MyClassLoader extends ClassLoader {

public CustomClassLoader(){
//getClassLoader returns ClassLoader
super(CustomClassLoader.class.getClassLoader());
}

}

//lot of thing after this

Tuesday, January 01, 2008

MyClassLoader - Java ClassLoader

I am very new to Java and often terms like ClassLoader, Virtual Machine scares me before start. With little of courage I start reading some of the documents on ClassLoader and ahh I find it very simple. Actually with reply to some of my old blog's comment, we had made a statement that "you can have your own classLoader in java".

The good part about ClassLoader - its written in Java :-). So one can expect code to be simple and more understandable than written in C++.

ClassLoader is nothing but a part of Java Virtual Machine responsible to load classes into memory. From where ? From local hard drive(mostly), from network and in some cases from browser. Little complex yet beautiful part of it is it load classes on demand not all at once. Java has an excellent feature to write your own classLoader which extends to ClassLoader class. Here, I named it as MyClassLoader :-). But if JVM has a classLoader why to write another one ? In my case, just for fun :D but there are other uses. One I got, is to automatically verify digital signature before invoking untrusted code. Second and more important when you want to update class at runtime. So, in this case we need to create another instance of our classLoader and then we can replace the already loaded classes with new updated classes. We can see some other usages as we move on to the blog.

I start reading some code here and there of classLoader from openjdk. If you have openjdk on your system, I will better suggest to go through some of the API implementation of ClassLoader. You will get the ClassLoader.java at path \jdk\src\share\classes\java\lang\ClassLoader.java. I was surprised to see that very less changes has been made to this file after jdk 1.2 and a great enhancement is done on jdk 1.2. In the code, you can see most of the API's have written in 1.2 only.

When java got released the most exciting and eye catching feature is how it execute code on the fly from remote server. Some kind of magic ? Yes, this magic is possible because java has the ability to write a custom classloader. The magic is this - in appletviewer/browser instead of looking into local had disk for classes it looks for remote server, loads the raw data through http and turns them into classes(duty of method called defineClass in ClassLoader, we will see this in more detail) inside Virtual Machine.

I am still in the midway of many document, reading re-reading and trying to understand more of it. We will try to see some of the method(s) which we need to implement for our custom ClassLoader, MyClassLoader. Most of the methods sounds easy but some methods like defineClass which is actually converting raw data into classes may go little complex.