Solved

Why ClassPath parameter does not work when I run a JAR?!

Posted on 2010-08-28
6
560 Views
Last Modified: 2012-06-27
Hi.

I have created a JAR file in Eclipse (Eclipse Java EE IDE for Web Developers. Version: Helios Release. Build id: 20100617-1415).

Then I'm starting it using a bat file (see enclosed code # 1) but I'm getting the following error:
ERROR(java.lang.ClassNotFoundException): COM.ibm.db2.jdbc.app.DB2Driver

So, I think that means that java.exe ignored my -cp "%JdbcRef%" parameter because db2java.zip is exactly the file which contains the required class.

Question are:
1) Why java ignoring ClassPath I have specified?
How to make it working?

2) Is it possible to override (or add more pathes to) the CLASSPATH specified inside a JAR in the ".classpath" file?

3) Why it hang at the Class.forName("COM.ibm.db2.jdbc.app.DB2Driver") if code in my JAR starts another copy of java.exe and run the same JAR with different parameters?

Notes:
a) I know for sure - database parameters are correct - when I'm running it under debugger in Eclipse it works fine. So, problems exists only when I run a JAR.

b) Eclipse configured to use the same JRE (see the %JavaHome% in a bat file example). So, it cannot be because of different JRE.

Regards,
Dmitry.
@echo off

set JavaDir=C:\Program Files (x86)\IBM\SQLLIB\java
set JavaHome=%JavaDir%\jdk\jre
set JdbcRef=%JavaDir%\db2java.zip

echo "%JavaHome%\bin\java.exe" -cp "%JdbcRef%" -jar JavaCslMon.jar TxMonitor -mode=test -test=database

"%JavaHome%\bin\java.exe" -cp "%JdbcRef%" -jar JavaCslMon.jar TxMonitor -mode=test -test=database

Open in new window

private string dbDriverName = "COM.ibm.db2.jdbc.app.DB2Driver";
private string dbName = "PT2010A";
private string dbUser = "uzver";
private string dbPassword = "pazzw0rd";

public Connection getConnection() throws Exception
{
	if (this.dbConn != null) return this.dbConn;
	
	MiscUtils.toLogger(Level.WARNING, String.format("Trying db driver (%1$s) ...", this.dbDriverName));
	try
	{
		Class c = Class.forName(this.dbDriverName, false, this.getClass().getClassLoader());
		this.dbDriver = (Driver)c.newInstance();
		MiscUtils.toLogger(Level.WARNING, String.format("* Db driver (%1$s): found", this.dbDriverName));
	}
	catch (ClassNotFoundException exc)
	{
		MiscUtils.toLogger(Level.WARNING, String.format("! Db driver (%1$s).ERROR(%2$s): %3$s", this.dbDriverName,
				exc.getClass().getName(), exc.getMessage()));
		exc.printStackTrace();
	}
	
	MiscUtils.toLogger(Level.WARNING, String.format("Trying to connect db (%1$s) as (%2$s) ...", this.dbName, this.dbUser));
	try
	{
		//this.dbConn = DriverManager.getConnection(this.dbName, this.dbUser, this.dbPassword);
		
		Properties props = new Properties();
		props.setProperty("user", this.dbUser);
		props.setProperty("password", this.dbPassword);
		
		this.dbConn = this.dbDriver.connect(this.dbName, props);
		
		MiscUtils.toLogger(Level.WARNING, String.format("* Db successfully connected."));
	}
	catch (SQLException exc)
	{
		MiscUtils.toLogger(Level.WARNING, String.format("! Fail to connect database (%1$s)! ERROR(%2$s): %3$s", this.dbName,
				exc.getClass().getName(), exc.getMessage()));
		exc.printStackTrace();
	}
	
	MiscUtils.toLogger(Level.WARNING, String.format("Trying to configure db connection..."));
	try
	{
		this.dbConn.setAutoCommit(false);
	}
	catch (SQLException exc)
	{
		MiscUtils.toLogger(Level.WARNING, String.format("! Fail to configure database connection! ERROR(%1$s): %2$s", 
				exc.getClass().getName(), exc.getMessage()));
	}
	
	return this.dbConn;
}

Open in new window

0
Comment
Question by:Dmitry_Bond
  • 2
  • 2
  • 2
6 Comments
 
LVL 86

Accepted Solution

by:
CEHJ earned 250 total points
ID: 33550576
When using the -jar argument. the classpath is ignored. The Class-Path attribute inside the jar is used instead. You need to do
"%JavaHome%\bin\java.exe" -cp "%JdbcRef%";JavaCslMon.jar TxMonitor -mode=test -test=database

Open in new window

0
 

Author Comment

by:Dmitry_Bond
ID: 33550645
Waw, super! Yes, true, this works:

"%JavaHome%\bin\java.exe" -cp "JavaCslMon.jar;%JdbcRef%" TxMonitor -mode=test -test=database

BUT(!) next part of problem - why java.exe ignoring the CLASSPATH?
For example if I change command to

"%JavaHome%\bin\java.exe" -cp "JavaCslMon.jar" TxMonitor -mode=test -test=database

Then it stops to work with the "java.lang.ClassNotFoundException: COM.ibm.db2.jdbc.app.DB2Driver" error. BUT WHY?!
I clearly see that the CLASSPATH environment variable contains the required path. So, if I add the "echo CP: [%CLASSPATH%]" command to a bat file I see following output:

CP: [.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip;C:\PROGRA~2\IBM\SQLLIB\java\db2java.zip;C:\PROGRA~2\IBM\SQLLIB\java\db2jcc.jar;C:\PROGRA~2\IBM\SQLLIB\java\sqlj.zip;C:\PROGRA~2\IBM\SQLLIB\java\db2jcc_license_cu.jar;C:\PROGRA~2\IBM\SQLLIB\bin;C:\PROGRA~2\IBM\SQLLIB\java\common.jar]

And there is I can see the required ZIP file - C:\PROGRA~2\IBM\SQLLIB\java\db2java.zip.
Question is - why java.exe cannot find it?
Is there any option to make java.exe use %CLASSPATH% + the pathes in "-cp" command line parameter?
0
 
LVL 92

Expert Comment

by:objects
ID: 33550712
you can use this:

"%JavaHome%\bin\java.exe" -cp "JavaCslMon.jar";%CLASSPATH% TxMonitor -mode=test -test=database
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 92

Assisted Solution

by:objects
objects earned 250 total points
ID: 33550722
0
 

Author Comment

by:Dmitry_Bond
ID: 33550755
Ok, thanks.
Seems I have solved my problems with CLASSPATH.
So, now my solution is:

use the following code in a bat file:

    set CLASSPATH=.\JavaCslMon.jar;%CLASSPATH%
    "%JavaHome%\bin\java.exe" TxMonitor

So, later when it starts another java.exe from application code it will re-use environment of existing process and should works fine.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 33552345
:-)
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This video teaches viewers about errors in exception handling.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now