Wednesday, January 07, 2009
Monday, December 15, 2008
Automating DOS Command Shell (batch file) multiple Inputs
Another wonderful problem I had been working was automate the command line input of a batch file. I have used redirect and pipe in both <x>nix and Windows platforms but had to spend more hours in troubleshooting this particular issue as there was no generally knows answers.
I've a batch file which takes couple of input by prompting at the shell. The content of the batch file named 'askquestion.bat' is given below:
It prompts for two inputs - name and age. But the age could be validated and prompted more than once if required. For avoiding infinite loop, the validation will be done for 5 wrong retries.
The common attempt to automate the input would be though using pipe. For single input, we can use echo
c:\>echo Thilak | askquestion.bat
This does not give input for second question and so the script runs on the unfinished (not sure what state it will be) pipe without input causing the script to run 5 retries (or infinitely without that retries check).
How to give multiple input?
Attempt 1:
c:\>echo Thilak\n35 | askquestion.bat
Attempt 2:
c:\>for %a in (Thilak 35) do echo %a | askquestion.bat
Attempt 3:
Create a file with answers in each line and save with a name answer.txt
c:\>type answer.txt | askquestion.bat
Attempt 4:
c:\>echo Thilak & echo 32 | askquestion.bat
Attemp 5:
c:\>(echo Thilak & echo 32) | askquestion.bat
Most of the common approaches failed. This mean to me that there it is a challenge for me. I took it up and started working on it. Google-ing and forum postings did not give answer to the specific scenario.
Dragged further by the attempt 3, I used dir instead of type. Luckily there were lots of files in that folder and my first observation itself gave me a clue.
c:\>dir | askquestion.bat
The important observation is that, the script received it's second input. And the input was taken after 1023 characters. So, this number is a well know one and I was able to do few assumptions quickly that the DOS shell input buffer is of size 1024 and the last character has to be NULL '\0' and so, 1023 character can be taken as input and flushed to receive the next set of inputs.
Now I started changing my answer.txt to have each answer to be of 1023 characters in each line. Line should be terminated with \n (\r\f or [cr][lf]). Basically I used spaces as the filler and it reflected immediately as a wrong choice. I should have used '\0' (NULL) as the fillers, but how? Then I tried another approach - First line with the actual data followed with dummy lines to fill the rest of the 1023 bytes and then the next actual data. During this, I realized that the last answer does not require to follow with the filler.
This was hard to get automated and did not spend much time in using the shell commands. I used to do Perl scripting and thought of using it here. The file name is 'ansquestion.pl'.
my @ans=("Thilak", "10");
open(QUESTION, "|cmd.exe /c askquestion.bat") or die "psht! problem while open.\n";
foreach(@ans){
$|=1;
print QUESTION pack("a1023", ($_, "\n"));
}
close(QUESTION) or die "problem while close";
The Perl pack() method was very handy to solve the filler issue. In the above code, the pack method creates a character byte stream of length 1023 filled with the list of arguments and remaining bytes with NULL. Following command would fulfill my requirement.
c:\>ansquestion.pl | askquestion.bat
Hopefully, someone can find a batch file to generate this output using for, if and echo commands.
I've a batch file which takes couple of input by prompting at the shell. The content of the batch file named 'askquestion.bat' is given below:
@echo off
:step1
set A1=
set A2=
set /a COUNT=1
:step2
set /p A1=What is your name?
echo Hi %A1%,
:step3
set /p A2=How old are you?
if "%A2%"=="" set A2=0
set /a A2=1+("%A2%")-1 > nul 2>&1
if not ERRORLEVEL 0 set A2=0
if /i "%1"=="noval" goto :step4
if %A2% LEQ 0 (
echo %A1%, '%A2%' may not be a valid age, please try again.
set /a COUNT+=1
if %COUNT% GEQ 5 goto :step4
goto :step3
)
:step4
if %A2% LEQ 10 echo Welcome kid
echo Name:%A1%, Age:%A2%
echo bye
set A1=
set A2=
set COUNT=
It prompts for two inputs - name and age. But the age could be validated and prompted more than once if required. For avoiding infinite loop, the validation will be done for 5 wrong retries.
The common attempt to automate the input would be though using pipe. For single input, we can use echo
c:\>echo Thilak | askquestion.bat
This does not give input for second question and so the script runs on the unfinished (not sure what state it will be) pipe without input causing the script to run 5 retries (or infinitely without that retries check).
How to give multiple input?
Attempt 1:
c:\>echo Thilak\n35 | askquestion.bat
Attempt 2:
c:\>for %a in (Thilak 35) do echo %a | askquestion.bat
Attempt 3:
Create a file with answers in each line and save with a name answer.txt
c:\>type answer.txt | askquestion.bat
Attempt 4:
c:\>echo Thilak & echo 32 | askquestion.bat
Attemp 5:
c:\>(echo Thilak & echo 32) | askquestion.bat
Most of the common approaches failed. This mean to me that there it is a challenge for me. I took it up and started working on it. Google-ing and forum postings did not give answer to the specific scenario.
Dragged further by the attempt 3, I used dir instead of type. Luckily there were lots of files in that folder and my first observation itself gave me a clue.
c:\>dir | askquestion.bat
The important observation is that, the script received it's second input. And the input was taken after 1023 characters. So, this number is a well know one and I was able to do few assumptions quickly that the DOS shell input buffer is of size 1024 and the last character has to be NULL '\0' and so, 1023 character can be taken as input and flushed to receive the next set of inputs.
Now I started changing my answer.txt to have each answer to be of 1023 characters in each line. Line should be terminated with \n (\r\f or [cr][lf]). Basically I used spaces as the filler and it reflected immediately as a wrong choice. I should have used '\0' (NULL) as the fillers, but how? Then I tried another approach - First line with the actual data followed with dummy lines to fill the rest of the 1023 bytes and then the next actual data. During this, I realized that the last answer does not require to follow with the filler.
This was hard to get automated and did not spend much time in using the shell commands. I used to do Perl scripting and thought of using it here. The file name is 'ansquestion.pl'.
my @ans=("Thilak", "10");
open(QUESTION, "|cmd.exe /c askquestion.bat") or die "psht! problem while open.\n";
foreach(@ans){
$|=1;
print QUESTION pack("a1023", ($_, "\n"));
}
close(QUESTION) or die "problem while close";
The Perl pack() method was very handy to solve the filler issue. In the above code, the pack method creates a character byte stream of length 1023 filled with the list of arguments and remaining bytes with NULL. Following command would fulfill my requirement.
c:\>ansquestion.pl | askquestion.bat
Hopefully, someone can find a batch file to generate this output using for, if and echo commands.
Friday, March 07, 2008
My Mobile Story
In today's world, people are more vulnerable to new technologies so easily. I mean it as I could see a drastic adoption of Mobile phone over the land line phone. It all started with only one convenience - be reachable on move. And now, that has come to a stage where the rest of the technology needs to live in this piece of solution.
When I was out of my college, I saw mobile phone which were bulky like walkie-talkie. I heard from the owners that the call rates were arbitrarily high that they use it to get and give the famous 'missed call'. It was used much like a Pager. I was not excited by this.
The time was changing and 'incoming calls' were announced as free of cost. By that time, I got engaged. And badly felt the need for a way to have calls in privacy. Went to a shop in Bangalore with one of my friend and bought a then slim & flip model mobile phone - Ericsson T28s along with connection from SPICE network. I did not have enough information like today to search for the best mobile. This model did attracted me at the first sight. I used it to the most but for voice calls, SMS and address book only. It worked well for 2 years of use until my kid spoiled it with water. The body of the phone was so sturdy that even after multiple drops it did not have any scratch or broken edge.
It was time to get a new phone, now the reason has become that just to be reachable. I went for another best of class mobile - Nokia 3315. I believe this model to be a best as the casing and features were just what I needed. You may be surprised, I used this phone for more than 6 years and that too without changing the original battery. When I 'packed' it, the battery was keeping my phone alive for 3 full days max or 60 min of talk time.
Recently I went for a new mobile, but this time my requirements were different. Professional and personal needs. I did many analysis with many from old to latest 'available' models. Four were my final choices - Moto Rokr E6, Sony Ericsson P1, HTC Touch and Nokia E50. Finally Nokia E50 won the race due to it's compact form, price, business features and software availability. I'm still a satisfied customer of SPICE network and hence did not change it yet.
When I was out of my college, I saw mobile phone which were bulky like walkie-talkie. I heard from the owners that the call rates were arbitrarily high that they use it to get and give the famous 'missed call'. It was used much like a Pager. I was not excited by this.
The time was changing and 'incoming calls' were announced as free of cost. By that time, I got engaged. And badly felt the need for a way to have calls in privacy. Went to a shop in Bangalore with one of my friend and bought a then slim & flip model mobile phone - Ericsson T28s along with connection from SPICE network. I did not have enough information like today to search for the best mobile. This model did attracted me at the first sight. I used it to the most but for voice calls, SMS and address book only. It worked well for 2 years of use until my kid spoiled it with water. The body of the phone was so sturdy that even after multiple drops it did not have any scratch or broken edge.
It was time to get a new phone, now the reason has become that just to be reachable. I went for another best of class mobile - Nokia 3315. I believe this model to be a best as the casing and features were just what I needed. You may be surprised, I used this phone for more than 6 years and that too without changing the original battery. When I 'packed' it, the battery was keeping my phone alive for 3 full days max or 60 min of talk time.
Recently I went for a new mobile, but this time my requirements were different. Professional and personal needs. I did many analysis with many from old to latest 'available' models. Four were my final choices - Moto Rokr E6, Sony Ericsson P1, HTC Touch and Nokia E50. Finally Nokia E50 won the race due to it's compact form, price, business features and software availability. I'm still a satisfied customer of SPICE network and hence did not change it yet.
Monday, February 25, 2008
Java and Perl
When launching an executable created using Perl archive mechanism or kick starting the Perl interpreter from within Java, one might get into an issue of improper i/o handling in their Perl modules. I've not come across a solution so far. The temporary workaround tried is to launch the Perl application in a command shell like
cmd /start /wait <path to perl.exe> <arguments>
cmd /start /wait <path to perl.exe> <arguments>
Java and Plugin for Win Runner
There was an interesting issue identified, that Win Runner with 1.5 Java Plugin is able to sense 1st window but not the second. It works well if the tool is executed for second time.
Win Runner was launching the Java application and tries to sense a window and its controls. The Java application was using 1.5 private JRE. Private JRE is nothing but bundling a separate copy of JRE along with an application. Public JRE is the one (but mostly many versions of it) available in C:\Program Files\Java\ folder.
Java 1.5 and later versions come with a feature for quick startup. This feature does have a penalty at the first run while creating a jsa file required for quicker startup in later runs. In the context of the issue, the Java application was taking time to show the first window. The Win Runner script used for detecting the window was able to wait and detect it. But there was a time gap for showing second window. In this period Win Runner detection API comes out with -1 (unknown error). After investigation, the first JVM launches another JVM and when there is a point where no JVM is available for Win Runner Java Plugin to work with, it is skipping the process of detecting the Java window by returning -1. There are many valid error return values for the detecting API but -1 is not part of it and code gets skipped in the execution flow.
Adding a validation for -1 and looping the check until some time frame resolved the issue. Looping is important here as Win Runner APIs do have timeout argument. But will not be effective as there is no JVM attached.
Win Runner was launching the Java application and tries to sense a window and its controls. The Java application was using 1.5 private JRE. Private JRE is nothing but bundling a separate copy of JRE along with an application. Public JRE is the one (but mostly many versions of it) available in C:\Program Files\Java\ folder.
Java 1.5 and later versions come with a feature for quick startup. This feature does have a penalty at the first run while creating a jsa file required for quicker startup in later runs. In the context of the issue, the Java application was taking time to show the first window. The Win Runner script used for detecting the window was able to wait and detect it. But there was a time gap for showing second window. In this period Win Runner detection API comes out with -1 (unknown error). After investigation, the first JVM launches another JVM and when there is a point where no JVM is available for Win Runner Java Plugin to work with, it is skipping the process of detecting the Java window by returning -1. There are many valid error return values for the detecting API but -1 is not part of it and code gets skipped in the execution flow.
Adding a validation for -1 and looping the check until some time frame resolved the issue. Looping is important here as Win Runner APIs do have timeout argument. But will not be effective as there is no JVM attached.
Thursday, February 08, 2007
Importing JavaScript file in another
Including an existing code should help almost every programmer from rewritting and testing it again. With any common programming language there will be either an include or import statement. When I tried to get a similar support in JavaScript, the feature is not there yet !!!
Why wait for someone to provide the support ? With small changes in the common javascript code and a javascript function which will import that script file will do the magic. Ofcourse, the usage is very limited but surely can be extended as your own wish and imagination. This script will currently work on Microsoft Windows' Scripting Environment.
The javascript function which imports another JavaScript file:
The function call usage:
var g=importjs("importable.js");
if(g!="") eval(g);
After the file has been imported, the function or global variables from the other file can be accessed from this importing script file as usual.
A sample "importable.js" content:
//GLOBAL-START
var g_global=true;
//GLOBAL-END
function deinit( one , two){
WScript.Echo("deinit "+one+" "+two);
}
function init(){
WScript.Echo("init");
}
function alert(message){
WScript.Echo("alert "+message);
}
//GLOBAL-START
WScript.Echo("global - single line statement");
if (true) {
var local="localvalue";
WScript.Echo("global - multi line (if) statement");
alert("global - calling another function (alert) in global scope");
alert("global - accessing a global variable - g_global="+g_global);
alert("global - accessing a local variable - local="+local);
}
//GLOBAL-END
Sure, you could find bugs in this code. Please post them :)
Why wait for someone to provide the support ? With small changes in the common javascript code and a javascript function which will import that script file will do the magic. Ofcourse, the usage is very limited but surely can be extended as your own wish and imagination. This script will currently work on Microsoft Windows' Scripting Environment.
The javascript function which imports another JavaScript file:
/////////////////////////////////////////////////////////////////////////////////////////
// SUPPORTED SYNTAX
//
// //FUNCTION-START
// function fn_name([args[,args]]){
// }
// //FUNCTION-END
//
// //GLOBAL-START
// var g_name;
// fn_name();
// //GLOBAL-END
//
// NOTE: Multiline comment (/**/) is not stripped.
// Singleline comment (//) and empty lines are stripped.
//
// USAGE: var global_stmt=importjs("path2js");
// if (global_stmt!="") eval(global_stmt);
//
////////////////////////////////////////////////////////////////////////////////////////
var ____err_count=0;
function importjs(filename){
var line_num=0
var file=(WScript.CreateObject("Scripting.FileSystemObject")).OpenTextFile(filename, 1, false, 0);
var fn_re=/^\s*function\s+(\S+)\s*\(([^\)]*)\)(.*)/g;
var script="",line="",prototype="",global="";
var fn, gen_gl=false, gen_fn=true;
while(true){
try{line=file.Readline();line_num++;}catch(fileread){break;}
if(null!=line.match(/FUNCTION.START/g)){gen_fn=true;continue;}
if(null!=line.match(/FUNCTION.END/g)){gen_fn=false;continue;}
if(null!=line.match(/GLOBAL.START/g)){gen_gl=true;continue;}
if(null!=line.match(/GLOBAL.END/g)){gen_gl=false;continue;}
if((line=line.replace(/(^|[^:])\/\/.*$/g,"$1"))=="")continue;//comment but not url
if(line.replace(/^\s+/g,"")=="")continue;//empty line
if(gen_gl){
try{
global+=("\n"+line);
}catch(e){
____err_count++;
WScript.Echo("error:"+e.message+" in "+filename+":"+line_num);
WScript.Echo(line);
}
}else if(gen_fn){
fn=fn_re.exec(line);
if (fn!=null && fn.length==4){
var arg="";
if(fn[2]!=null && fn[2]!=""){
var args=(fn[2]).split(", ");
for(i in args){
if(i>0) arg+=",";
arg+=("\""+args[i].replace(/\s+/g, "")+"\"");
}
if (arg!="") arg+=",";
}
if (prototype!=""){
try{
eval(prototype+script+"+\"\");");
}catch(e){
____err_count++;
WScript.Echo("error:"+e.message+" in "+filename+":"+line_num);
WScript.Echo(prototype+script+"+\"\");");
}
}
prototype=fn[1]+"=new Function("+arg+"\"";
script=fn[3].replace(/("|\\|')/g, "\\$1")+"\"";//"
}else{
script+=("\n+\""+line.replace(/("|\\|')/g, "\\$1")+"\"");//"
}
}
}
if (prototype!=""){
try{
eval(prototype+script+"+\"\");");
}catch(e){
____err_count++;
WScript.Echo("error:"+e.message+" in "+filename+":"+line_num);
WScript.Echo(prototype+script+"+\"\");");
}
}
//WScript.Echo(""+____err_count+" error(s) found.");
return global;
}
The function call usage:
var g=importjs("importable.js");
if(g!="") eval(g);
After the file has been imported, the function or global variables from the other file can be accessed from this importing script file as usual.
A sample "importable.js" content:
//GLOBAL-START
var g_global=true;
//GLOBAL-END
function deinit( one , two){
WScript.Echo("deinit "+one+" "+two);
}
function init(){
WScript.Echo("init");
}
function alert(message){
WScript.Echo("alert "+message);
}
//GLOBAL-START
WScript.Echo("global - single line statement");
if (true) {
var local="localvalue";
WScript.Echo("global - multi line (if) statement");
alert("global - calling another function (alert) in global scope");
alert("global - accessing a global variable - g_global="+g_global);
alert("global - accessing a local variable - local="+local);
}
//GLOBAL-END
WScript.Echo("global - single line statement, but will not be executed");
Sure, you could find bugs in this code. Please post them :)
Saturday, May 13, 2006
Java Hotspot VM : Server Or Client
As a developer, if you have installed a JDK (Java Development Kit)1 downloaded from java.sun.com, you might have noticed that there are two versions of Java Hotspot VM to use. They are JIT (Just-in-Time) compilers for the Java Interpreter to improve the performance of the targeted applications. Broadly there are two types of application - client or server, thus there are two versions of Java Hotspot VM - Client and Server. These two options should not be confused with that the Client VM can communicate with the Server VM. One instance of a Java VM can use2 either a Client or Server Hotspot VM.
The Hotspot (or JIT) compiler technology is the one which boosts the Java performance by interfacing the Java platform and the actual underlying platform. Hotspot provides comparable performance with native applications as the optimization is done on-the-fly, during runtime.
Both are implemented as separate binaries (windows: %JAVA_HOME%\bin\{client|server}; solaris & linux: $JAVA_HOME/lib/$ARCHITECTURE/{client|server}). The Java launcher (${JAVA_HOME}/bin/java[.exe]) chooses the required hotspot VM based on the command line arguments. Though there are two hotspot VMs available, a developer cannot target his Java code for a particular3 VM. Java byte-code is 100% compatible with both the hotspot VMs.
There is also an option available to disable both the hotspot VMs. Use -Xint (interpreter mode) . Please note that this also requires any one of the hotspot VM's interpreter, if nothing is specified the default one is used.
To change the default VM, move your default choice in the file $JAVA_HOME/lib/$ARCHITECTURE/jvm.cfg to be the first uncommented line.
1. JDK has been known in many forms: JavaTM 2 Platform Standard Edition Development Kit 5.0 with '1.5.0' or 'tiger', J2SE Software Development Kit with '1.4.2' or 'mantis', Java SE Development Kit 6 (the next major release - 'mustang').
The Hotspot (or JIT) compiler technology is the one which boosts the Java performance by interfacing the Java platform and the actual underlying platform. Hotspot provides comparable performance with native applications as the optimization is done on-the-fly, during runtime.
Both are implemented as separate binaries (windows: %JAVA_HOME%\bin\{client|server}; solaris & linux: $JAVA_HOME/lib/$ARCHITECTURE/{client|server}). The Java launcher (${JAVA_HOME}/bin/java[.exe]) chooses the required hotspot VM based on the command line arguments. Though there are two hotspot VMs available, a developer cannot target his Java code for a particular3 VM. Java byte-code is 100% compatible with both the hotspot VMs.
% java -client -versionA Hotspot Client VM is suitable for any short-lived applications like a Java Applet in a web browser or UI application on desktops. Client VM makes the application load faster, does few optimizations compared to Server VM, identifies a hotspot (code that is used heavily by the application which can be optimized) very sooner than the Server VM. Also it uses different set of GC (garbage collection) algorithms than the Server VM. With tiger (1.5.0), Client JVM started sharing the core classes between instances by Class Data Sharing feature. This speeds up the application startup and reduces the memory footprint. The -version output above gives the information whether the JVM is using shared classes sharing. This is not available for Server VM.
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)
% java -server -versionServer VM is best suitable for all long running applications like Application Servers, Web Servers and so. This class VM does more levels optimizations enabled the server applications run faster. With a long running Java process, the amount of garbage created is also very high and proportionate to the heap size (-Xms, -Xmx). With very big heaps, the GC might need more time to clean up. To overcome such issues, Server VM comes with many GC algorithms to choose from. There is also verity of flags and command line options available to fine tune the GC.
Java HotSpot(TM) Server VM (build 1.5.0_06-b05, mixed mode)
There is also an option available to disable both the hotspot VMs. Use -Xint (interpreter mode) . Please note that this also requires any one of the hotspot VM's interpreter, if nothing is specified the default one is used.
% java -Xint -server -versionMost downloaded configurations of a JRE (Java Runtime Environment) for Windows will have only Client Hotspot VM, unless the platform does not have a client VM.
Java HotSpot(TM) Server VM (build 1.5.0_06-b05, interpreted mode)
To change the default VM, move your default choice in the file $JAVA_HOME/lib/$ARCHITECTURE/jvm.cfg to be the first uncommented line.
1. JDK has been known in many forms: JavaTM 2 Platform Standard Edition Development Kit 5.0 with '1.5.0' or 'tiger', J2SE Software Development Kit with '1.4.2' or 'mantis', Java SE Development Kit 6 (the next major release - 'mustang').
Wednesday, May 10, 2006
Java ClassLoader : ClassNotFoundException Or NoClassDefFoundError
Java Virtual Machine loads the required classes (class could be a Java class or Java interface) through chain of class loaders. When a class is getting loaded there are possible cases where one can get an Exception or Error. This article might give some basics in handling these situations.
First, let's see the possible exceptions or errors that could raise during a class loading process :
java.lang.Exception
+->java.lang.ClassNotFoundException
java.lang.LinkageError
+->java.lang.NoClassDefFoundError
+->java.lang.ClassCircularityError
+->java.lang.ClassFormatError
+->java.lang.VerifyError
+->java.lang.IncompatibleClassChangeError
| +->java.lang.InstantiationError
| +->java.lang.AbstractMethodError
+->java.lang.ExceptionInInitializerError
java.lang.VirtualMachineError
+->java.lang.OutOfMemoryError
The most common exception or errors would be: ClassNotFoundException and NoClassDefFoundError. Both means the same information - not able to load a given class (or interface) from the known classpath. Then, why two types ?
Exception is something which a programmer should anticipate during his program execution. Which means - the code can fail, but should be able to recover from that using exception handlers. How can it happen ? The answer is - when using Java API (Application Programming Interface) to find and load the class. Java API provides java.lang.Class.forName(), using which a programmer can request the ClassLoader to find and load (if not already done) a class by providing it's String name.
From the API specification, Class.forName() can throw any one of these when it is not able to find and load the requested class: ClassNotFoundException and LinkageError (any subclass of it).
On the other hand a programmer should not anticipate an Error in his program execution. Though some errors are catchable, it is not advisable. The reason being, the Java VM has identified it as an Error and it's internal state may get affected if the program continues to run with that error. When the JVM is very sure about the Error, it gives out the message and shuts down itself. OutOfMemoryError is a good example. When JVM decides that there is no space for any new object, it gives out the message and comes down.
The following code uses a class which was available during the compilation of this class, but not available during runtime. This throws NoClassDefFoundError. Here there is no API being used to construct the class or instance of it. This line (new operator) requires the class to be loaded and initialized to create an instance of it. Thereby this statement has to throw an Error, which should not be caught. NoClassDefFoundError is a subclass of LinkageError, meaning that this error has occurred during linking a class.
Internally, JVM uses ClassLoaders to search a class and recieves the ClassNotFoundException. This will get converted into NoClassDefFoundError, if the class loading operation is initiated by the JVM. You would get the same error if you run the following command:
First, let's see the possible exceptions or errors that could raise during a class loading process :
java.lang.Exception
+->java.lang.ClassNotFoundException
java.lang.LinkageError
+->java.lang.NoClassDefFoundError
+->java.lang.ClassCircularityError
+->java.lang.ClassFormatError
+->java.lang.VerifyError
+->java.lang.IncompatibleClassChangeError
| +->java.lang.InstantiationError
| +->java.lang.AbstractMethodError
+->java.lang.ExceptionInInitializerError
java.lang.VirtualMachineError
+->java.lang.OutOfMemoryError
The most common exception or errors would be: ClassNotFoundException and NoClassDefFoundError. Both means the same information - not able to load a given class (or interface) from the known classpath. Then, why two types ?
Exception is something which a programmer should anticipate during his program execution. Which means - the code can fail, but should be able to recover from that using exception handlers. How can it happen ? The answer is - when using Java API (Application Programming Interface) to find and load the class. Java API provides java.lang.Class.forName(), using which a programmer can request the ClassLoader to find and load (if not already done) a class by providing it's String name.
From the API specification, Class.forName() can throw any one of these when it is not able to find and load the requested class: ClassNotFoundException and LinkageError (any subclass of it).
Class c = null;
try {
c = Class.forName("AVeryNewClassName");
info.log("Using custom settings...");
} catch(ClassNotFoundException handle) {
// handle the exception
info.log("Using default settings...");
c = DEFAULT_CLASS;
}
On the other hand a programmer should not anticipate an Error in his program execution. Though some errors are catchable, it is not advisable. The reason being, the Java VM has identified it as an Error and it's internal state may get affected if the program continues to run with that error. When the JVM is very sure about the Error, it gives out the message and shuts down itself. OutOfMemoryError is a good example. When JVM decides that there is no space for any new object, it gives out the message and comes down.
The following code uses a class which was available during the compilation of this class, but not available during runtime. This throws NoClassDefFoundError. Here there is no API being used to construct the class or instance of it. This line (new operator) requires the class to be loaded and initialized to create an instance of it. Thereby this statement has to throw an Error, which should not be caught. NoClassDefFoundError is a subclass of LinkageError, meaning that this error has occurred during linking a class.
CompileTimeOnlyClass c = new CompileTimeOnlyClass();
or
CompileTimeOnlyClass.invokePublicStaticMethod();Internally, JVM uses ClassLoaders to search a class and recieves the ClassNotFoundException. This will get converted into NoClassDefFoundError, if the class loading operation is initiated by the JVM. You would get the same error if you run the following command:
% java NotYetCompiledClass
Exception in thread "main" java.lang.NoClassDefFoundError: NotYetCompiledClass
Subscribe to:
Posts (Atom)