2

I have noticed an issue that crops up repeatedly: using an env var for the classpath on the java command line within a shell script does not work.

First off, let us see what does work: both using hard-coded classpath in a script as follows: (note: the "classpath is" statement is printed within the java program itself)

steve@mithril:/shared$     java -classpath .:/shared/mysql-connector-java-5.1.25-bin.jar DbPing com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql user password
classpath is .:/shared/mysql-connector-java-5.1.25-bin.jar
Attempting connection to com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql  password
Connecting to user using URL=jdbc:mysql://localhost:3306/mysql
Successfully connected.

and also using env var directly within the shell:

steve@mithril:/shared$ export CP=.:/shared/mysql-connector-java-5.1.25-bin.jar
steve@mithril:/shared$ java -classpath $CP DbPing com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql user password 
classpath is .:/shared/mysql-connector-java-5.1.25-bin.jar
Attempting connection to com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql  password
Connecting to user using URL=jdbc:mysql://localhost:3306/mysql
Successfully connected.

What does *not * work: running the same commands as shown above within a shell script:

steve@mithril:/shared$ cat dbping.mysql
CP=.:/shared/mysql-connector-java-5.1.25-bin.jar
echo $CP
java -classpath $CP DbPing com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql user password 
#java -classpath .:/shared/mysql-connector-java-5.1.25-bin.jar DbPing com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql user password 

steve@mithril:/shared$  ./dbping.mysql
.:/shared/mysql-connector-java-5.1.25-bin.jar
classpath is .:/shared/mysql-connector-java-5.1.25-bin.jar
Attempting connection to com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql  password
Could not load db driver com.mysql.jdbc.Driver
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:190)
    at DbPing.getConnection(DbPing.java:34)
    at DbPing.main(DbPing.java:22)
Exception in thread "main" java.sql.SQLException: com.mysql.jdbc.Driver
    at DbPing.getConnection(DbPing.java:41)
    at DbPing.main(DbPing.java:22)

Follow-up: The script had windows style newlines in it. Apparently the \r clobbered the internal environment variable. found this using

  od -cx

. I am going to give credit to stephen c anyways, since his prodding got me on the right track to finding the solution

2
  • I checked some scripts I have sitting around, and I've quoted my classpath arguments, though there's a glob in mine. Out of curiosity, do you get the same result with java -classpath "$CP" DbPing... ? Commented Jun 30, 2013 at 22:50
  • What prints the classpath is ... message? The standard java application launcher doesn't do that. Commented Jun 30, 2013 at 22:54

1 Answer 1

1

The symptoms you describe are rather puzzling. I can't see the problem (the script looks correct), but I've got an idea on how to start tracking it down.

  1. Get rid of the commented out lines from the script.

  2. Add a #!/bin/sh line to the start of the script to make sure that you are actually using the right shell to execute it. (It is always a good idea to do this ... even if you think that you will get the right shell by default. That might change, depending on the platform.)

  3. To figure out what the shell is doing, add set -vx as after the #!/bin/sh line.

The "-v" says echo each script line read, and the "-x" says echo the actual command lines that are executed. This will tell you exactly what commands are being run ... so that you can figure out what the command arguments really are.

Sign up to request clarification or add additional context in comments.

3 Comments

the "classpath is" statement is generated within the java DbPing program itself. I am using ubuntu so /bin/sh is same as /bin/bash but no matter i'll add the -vx
@javadba - You should ALWAYS put a #! line on any script. 1) documentation. 2) your script might need to be run on another platform in the future and you using a different shell could matter. 3) AFAIK there are behavioural differences between "/bin/sh" and "/bin/bash" even though they are the same executable ...
I found the issue was with windows style newlines in it. But i gave you credit for the answer since it helped get me looking closer at the script with a fine toothed comb.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.