Wednesday, May 27, 2009

What does rt.jar stand for in Java/JDK/JRE?

The most likely answer is, rt stands for RunTime. Some tend to think it stands for RooT, since this jar contains all java build-in classes. But I have yet to find any official Sun documents regarding this acronym.
Whether it stands for RunTime, RooT, or anything else is not important. The question I have is, why would the java creator chose to use such a undescriptive name. Maybe it can make your classpath shorter? But we rarely put rt.jar in system classpath.
Here are 2 reasons I don't like the name rt.jar:
* While experienced developers take it for granted, java beginners don't know what it is other than it's a jar. So it's one more questions in beginners' mind.
* The shorter the name, the easier it is to cause naming conflicts, at least visually. While rt.jar will always reside under $JAVA_HOME/jre/lib, it is possible your applications may have another jar also named rt.jar.
I know rt.jar will be with us as long as java is, but just for the sake of discussion, how would you name it differently? Maybe java.jar, or java-core.jar?
PS: What does jar stand for? Jar stands for Java Archive. A jar file usually has file name extension .jar. It contains mainly java class files but any types of files can be included, e.g., XML files, HTML files, properties files, gif/jpg image files, text files, PDF files, and binary files, and so on.
PS: What is the difference between a jar file and a zip file? Basically, a jar file is the same as a zip file, except that the jar file contains a META-INF directory to store metadata or attributes. The most well-known file is META-INF/MANIFEST.MF. You can customize the content of a MANIFEST.MF when creating a jar file, and if you don't, a default one is generated and included. For example:
Manifest-Version: 1.0
Created-By: 1.5.0_06 (Sun Microsystems Inc.)
It's perfectly fine to have other configuration files and directories under META-INF.

Java Jar File Naming Conventions and Examples.

util.jar is the worst jar file name I can think of. All I know is it contains some utility/helper classes. But it is unclear if they belong to an application server, or a framework, or any application sub-systems. You will need to ask someone or some docs to know what it is. It's part of the DataDirect JDBC Driver distribution.
On the other hand, good jar file names are always self-explanatory, for example: struts.jar, jboss-system.jar, commons-pool-1.1.jar
Some thoughts on jar file naming conventions:
1. Always use extension ".jar", not ".zip"
Theoretically, jar files can have any extension or no extension at all. If you specify it in the system classpath, it should be loadable. The problem is with automatic library detection and loading by containers and frameworks. It's expensive to scan all files so some sort of extension restriction is needed. For this reason, J2EE/JavaEE platform spec requires all library jar files use ".jar" extension, such as WEB-INF/lib/mybeans.jar.
2. Use hyphen (-) instead of underscore (_) as word separator
First, it's easier to type - than _; secondly, when the file name is underlined (e.g., in a hyperlink), the _ is invisible. Hyphen has been shunned in file names partly because it is an illegal character in java identifier. But this concern is unwarranted.
3. Append version number if distributed standalone
because they can be dropped into any applications, which may need specific versions. We don't want users to have to compare file size or extract some META-INF files to know its version. Some examples: hibernate3.jar, commons-logging-1.0.3.jar, and
log4j-1.2.8.jar.
4. Don't append version number if bundled inside other larger deliverables
because the enclosing deliverables, such as an application server (e.g., JBoss 4.0.4, jakarta-tomcat-5), a tool(e.g., apache-ant-1.6.5), aleady have the version numbers, thus no version number for jboss.jar, catalina.jar, and ant.jar.

The Worst Java Job Interview Questions.

Why are you looking for a job?
Strictly speaking, this is not a java question, but it shows up in almost every job interview I've been to. The interviewer is testing the candidate's motivation for a job change. Invariably, the answer will be something like, advancing career and professional development. Of course, the candidate won't tell you he/she is looking for a 15% salary increase to cover the gas price increase, or he doesn't get along with his co-workers, or he didn't get the promotion or bonus, or he was rated Under-Perform in last year's performance review.
Which OS do you use in your development work, Linux, Windows, or Solaris?
Java is cross-platform, and I couldn't care less about OS while I'm writing java code. Unless the job is specifically about porting applications to other OS and deploying/distributing applications, I don't see how this is relevant. J2EE, JavaEE and Web applications are all made up of components that are managed by the application server, and thus shielded from the underlying OS.
Are you familiar with Oracle Database, or DB2?
Java persistence can now be easily achieved with ORM frameworks such as Hibernate, TopLink. The latest release of EJB 3 and Java Persistence API has standardize the way persistence is done in Java, J2EE, and JavaEE. The goal of these industry efforts is to let Java developers forget database stuff, which should be left to DBA. Even if Java developers in this project need to deal with database directly, I suppose they need to know about database design concepts and SQL, not some Oracle or DB2 stored procedures.

A New Option in Jar Command in JDK 6

DK 6 adds a new feature to the jar command: e. Other options of the jar command are still the same. This is the partial usage from JDK 6 beta 2:
C:\tools\jdk6\bin>jar
Usage: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
Options:
...
-e specify application entry point for stand-alone application
bundled into an executable jar file
...
For example, I run jar command to package a self-contained application in a jar file:
C:\ws\nb\scrap\build\classes>C:\tools\jdk6\bin\jar cvfe ..\..\dist\hello-world.jar com.javahowto.test.HelloWorld com
added manifest
adding: com/(in = 0) (out= 0)(stored 0%)
adding: com/javahowto/(in = 0) (out= 0)(stored 0%)
adding: com/javahowto/test/(in = 0) (out= 0)(stored 0%)
adding: com/javahowto/test/HelloWorld.class(in = 572) (out= 348)(deflated 39%)
Then I can distribute hello-world.jar to users, who can run hello-world app like this:
C:\download\hello>java -jar hello-world.jar
Hello world!
Users can run it with any version of java; it doesn't have to be JDK 6. What the extra e option does is simply adding a Main-Class entry in the jar's META-INF\MANIFEST.MF:
Manifest-Version: 1.0
Created-By: 1.6.0-beta2 (Sun Microsystems Inc.)
Main-Class: com.javahowto.test.HelloWorld
This new feature is helpful when packaging simple self-contained apps, and application client modules in J2EE/JavaEE, both of them require a Main-Class entry in MANIFEST.MF. So I don't have to create one beforehand, or have Apache Ant generate one.

How to run Tomcat manager web application

1. Add the security role manager to $CATALINA_HOME/conf/tomcat-users.xml, and assign this role to a username, say tomcat:


2. Start Tomcat:
$CATALINA_HOME/bin/startup.sh
(%CATALINA_HOME%\bin\startup.bat on windows)
3. Browser the URL http://localhost:8080, and click the Tomcat Manager link on the upper-left corner. In the basic login page, enter username tomcat and password tomcat, as specified in conf/tomcat-users.xml. Tomcat Manager web application allows you to view Tomcat server info, deploy and undeploy webapps, and other simple management tasks.

Who set my CLASSPATH?

I never set CLASSPATH environment variable. Instead I always use the explicit -classpath or -cp options when running java, javac, javap, etc. The other day I was surprised to see a CLASSPATH environment variable is set:
C:\tmp> set CLASSPATH
CLASSPATH=.;C:\Program Files\Java\jre1.5.0_09\lib\ext\QTJava.zip
C:\tmp> dir "C:\Program Files\Java\jre1.5.0_09\lib\ext\QTJava.zip"
06/12/2006 09:57 AM 1,180,476 QTJava.zip
It seems when I installed apple's quicktime plugin, it automatically set this CLASSPATH in my environment. I don't like this. I always assume a clean environment when running any java applications. So I removed it:
C:\tmp> set CLASSPATH=
C:\tmp> set CLASSPATH
Environment variable CLASSPATH not defined
I can tolerate an installer modifying my PATH, but not CLASSPATH.

Line tools NetBeans plugin

I don't like overloading my IDE with a bunch of plugins, but this is a must-have for my NetBeans (currently version 5.5.1).
[Update] Those features in line tool has been integrated into NetBeans proper 6.x. So if you are running NetBeans 6.1 (the latest as of 5/2008), line tool plugin is no longer needed.
I use it everyday to copy and paste lines of text without using CTRL-C CTRL-V. This is its official description:
Line Tools Support following operations in text editors:
1. Move Line (or lines spanned by selection) Up
2. Move Line (or lines spanned by selection) Down
3. Copy Line (or lines spanned by selection) Up
4. Copy Line (or lines spanned by selection) Down
5. Sort lines spanned by selection in ascending order
6. Sort lines spanned by selection in descending order
7. Remove duplicate lines while sorting. Maintain the caret position, the selection and the order of start and end of the selection when moving/copying the lines.
This is the first plugin I will install for every new NetBeans release. Unfortunately, NetBeans can't automatically migrate my installed plugins.
Oddly, this plugin doesn't show up in the official NetBeans plugin portal. The place to go is the author's (Sandip Chitale) blog.
You can choose either download the *.nbm file and manually install it, or add a new update center (Sandip Chitale's update center) to your NetBeans. After adding the update center, you will able to download a lot more good stuffs by Sandip Chitale.

How to create a thread

Execution in Java always take form of a thread. In simple programs only one thread occurs, often referred to as the 'main thread'.
In some programs though concurrent threads is necessary, or if you are building a Swing application with for example a progress bar you don't want the main thread to handle the updates of the UI.
Then you create an additional thread to take care of that. There are two main ways of creating a thread. The first is to extend the Thread class and the second is to implement the Runnable interface.
Extending Thread:
 
public class MyThread extends Thread {
/**
* This method is executed when the start() method is called on the thread
* so here you will put the 'thread code'.
*/
public void run() {
System.out.println("Thread executed!");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Thread thread = new MyThread();
thread.start();
}
}
Implementing the Runnable interface:
 
public class MyRunnable implements Runnable {
/**
* As in the previous example this method is executed
* when the start() method is called on the thread
* so here you will put the 'thread code'.
*/
public void run() {
System.out.println("Thread executed!");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
//create a Thread object and pass it an object of type Runnable
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}

Setting thread priorities

Setting a threads priority can be very useful if one thread has more critical tasks to perform than another.
The Thread class has a method called setPriority(int level) with which you can alter the priority a Thread instance has.
The priority level range from 1 (least important) to 10 (most important) and if no level is explicitly set, a Thread instance has the priority level of 5.
In the first example below no priorites are set, so both threads have the priority level 5. The TestThread class implements the Runnable interface and in its
run() method loops from 1 to 10 and output the number along with its Thread id, which is passed to the constructor.
 
/**
* Main.java
*
* @author
*/
public class Main {
/**
* Starts two threads and wait for them to finish.
*/
public void setPrioritiesOnThreads() {
Thread thread1 = new Thread(new TestThread(1));
Thread thread2 = new Thread(new TestThread(2));
thread1.start();
thread2.start();
try {
//Wait for the threads to finish
thread1.join();
thread2.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Done.");
}
/**
* Starts the program
*
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().setPrioritiesOnThreads();
}
class TestThread implements Runnable {
int id;
public TestThread(int id) {
this.id = id;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread" + id + ": " + i);
}
}
}
}
 
 
 
Since both threads have the same priority, the output will be a mix between them and could look like this:
 
Thread2: 1
Thread1: 1
Thread2: 2
Thread1: 2
Thread2: 3
Thread1: 3
Thread2: 4
Thread1: 4
Thread2: 5
Thread1: 5
Thread2: 6
Thread1: 6
Thread2: 7
Thread2: 8
Thread2: 9
Thread2: 10
Thread1: 7
Thread1: 8
Thread1: 9
Thread1: 10
Done.
 
The output could look different from on execution to another since we have no control of how the CPU will prioritize them.
If we set the priority on the threads we still haven't got exact control of the execution, but at least we can tell the CPU which one we think is
most important. The next example is identical to the one above except for the lines where the priority of the threads are set:
 
/**
* Main.java
*
* @author
*/
public class Main {
/**
* Starts two threads, setting priorities on them
* and wait for them to finish.
*
*/
public void setPrioritiesOnThreads() {
Thread thread1 = new Thread(new TestThread(1));
Thread thread2 = new Thread(new TestThread(2));
//Setting priorities on the Thread objects
thread1.setPriority(Thread.MAX_PRIORITY);
thread2.setPriority(Thread.MIN_PRIORITY);
thread1.start();
thread2.start();
try {
//Wait for the threads to finish
thread1.join();
thread2.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Done.");
}
/**
* Starts the program
*
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().setPrioritiesOnThreads();
}
class TestThread implements Runnable {
int id;
public TestThread(int id) {
this.id = id;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread" + id + ": " + i);
}
}
}
}
 
 
The output from the code looked like this when executed:
 
Thread1: 1
Thread1: 2
Thread1: 3
Thread1: 4
Thread1: 5
Thread1: 6
Thread1: 7
Thread1: 8
Thread1: 9
Thread1: 10
Thread2: 1
Thread2: 2
Thread2: 3
Thread2: 4
Thread2: 5
Thread2: 6
Thread2: 7
Thread2: 8
Thread2: 9
Thread2: 10
Done.
 
It is however not certain that the first thread will be prioritized to finish before the second thread starts every time.
It is, as mentioned earlier, up to the CPU to decide.

Remove duplicate items from an ArrayList

This code example shows how to remove duplicate items from an ArrayList.

ArrayList arrayList1 = new ArrayList();
arrayList1.add("A");
arrayList1.add("A");
arrayList1.add("B");
arrayList1.add("B");
arrayList1.add("B");
arrayList1.add("C");
//Create a HashSet which allows no duplicates
HashSet hashSet = new HashSet(arrayList1);
//Assign the HashSet to a new ArrayList
ArrayList arrayList2 = new ArrayList(hashSet) ;
//Ensure correct order, since HashSet doesn't
Collections.sort(arrayList2);
for (Object item : arrayList2)
System.out.println(item);



Note that you will have to sort the ArrayList if you want to be sure that the items remain
in correct order by calling the sort method of the Collection class.
This will produce the following output:
A
B
C