Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

One CLASSPATH for development and for runtime environment?  RSS feed

 
AhFai Chan
Ranch Hand
Posts: 81
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi.

I am testing connection to Oracle11gR2. Java cannot find the OracleDriver!

My development env is 1.7.0 and my runtime env is 1.8.0

I have downloaded Oracle's latest jodbc6.jar and my CLASSPATH points to c:\Program Files\Java\jdk1.7.0_40\lib

I tried to run it in command line (cmd) and got the same error message as from eclipse, i.e. cannot find OracleDriver.

QUESTION1: does JRE look at the same CLASSPATH, which, in my case, is in the development environment?

QUESTION2: why can't Java find the ojdbc6.jar?


 
Stephan van Hulst
Saloon Keeper
Posts: 7809
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's always a bad idea to use a global classpath. You should specify the classpath per project, using either command line options, or project settings when you're using an IDE.

Your current problem is caused by the fact that jars aren't picked up when the classpath points to a folder that contains them. You need to point the classpath to each individual jar file, or put the jar files in the lib/ext folder of your virtual machine.
 
AhFai Chan
Ranch Hand
Posts: 81
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:It's always a bad idea to use a global classpath. You should specify the classpath per project, using either command line options, or project settings when you're using an IDE.

Your current problem is caused by the fact that jars aren't picked up when the classpath points to a folder that contains them. You need to point the classpath to each individual jar file, or put the jar files in the lib/ext folder of your virtual machine.


Can you please tell me why I have two JRE subdirectories:
c:\Program Files\Java\jdk1.7.0_40\jre
c:\Program Files\Java\jre1.8.0_66

Where in my PATHS and CLASSPATH points to the jre1.8.0?

Do you guys specify CLASSPATH as user environment variable or system environment variable and does it matter which one?

When I run a Java class, Java uses 1.8.0, but I have not explicitly specified that anywhere in the environment variables.

And thanks for tip on not using global classpath.
 
Stephan van Hulst
Saloon Keeper
Posts: 7809
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The JDK always comes with its own JRE. It's because developing applications is not very efficient if you can't run them.

The JDK installer usually asks you if you also want to install a public JRE, which is used when Java applications want to run on your system, not just ones that you are developing.

When installing the public JRE, symbolic links are added to the folder C:\ProgramData\Oracle\javapath. The installer will add this folder to the PATH environment variable. That's why the last installed public JRE is usually the one that is run when you run java in cmd.

Personally, I never install a public JRE, and I just add the environment variable JAVA_HOME to point to my JDK folder, and add %JAVA_HOME%\bin to my PATH variable.

CLASSPATH should NOT be set.
 
Dave Tolls
Rancher
Posts: 2914
36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:
... or put the jar files in the lib/ext folder of your virtual machine.


I can't think of a time when it is a good idea to do this.
If you have more than one app on your machine that use different version of the same jar file you'd be in for jar file hell.

Any dependencies for your application should be packaged with the application, with its own classpath in the manifest for your jar file.
 
Bhushan Bhawsar
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree with Dave. I think during development if you are using an IDE lets say Eclipse, you can easily add the required jars in your build path by updating the project settings. This way you will not face the issue while running the project in eclipse.
Now when you are running the project on an server lets say Unix, I think you might be calling the main method from shell ,perl or any other script. We can set the classpath in this script before the main method call and pass this classpath to our java call. By doing this we can have separate classpaths for different application running.

Let me know if you disagree.
 
Tim Holloway
Bartender
Posts: 18709
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
AhFai Chan wrote:
I have downloaded Oracle's latest jodbc6.jar and my CLASSPATH points to c:\Program Files\Java\jdk1.7.0_40\lib


That won't work.

Despite all the abuse that Java has taken in the security arena in recent times, Java was, in fact, designed from Day 1 to be secure. One of the things that was done to ensure that security was that mechanisms exists to keep people from just dropping classes into the JRE's core classpath. Only resources that have been properly authorized will be recognized.

Incidentally, rules are different when you are running appservers than when you are running stand-alone Applications. Most Java appservers build up one or more internal classpaths using rules partly defined by whatever standard architectures they implement (for example, J2EE) and partly by the appserver's own internal needs. And often they define custom classloaders to support that.

If you define a CLASSPATH environment variable for Tomcat, for example, that's not going to help, since Tomcat builds its internal classpaths from the Tomcat lib directory, the WEB-INF subdirectories of deployed webapps, and other pre-defined places.
 
J. Kevin Robbins
Bartender
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Holloway wrote:
If you define a CLASSPATH environment variable for Tomcat, for example, that's not going to help, since Tomcat builds its internal classpaths from the Tomcat lib directory, the WEB-INF subdirectories of deployed webapps, and other pre-defined places.

I may be wandering off-topic, but can you expand on this? I just checked our server and there is a classpath set for Tomcat. Will this cause a problem or is it just harmless but useless?

It's currently .:/usr/share/tomcat5/common/lib/:/usr/share/tomcat5/bin/

Yes, that's really version 5.
 
Tim Holloway
Bartender
Posts: 18709
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I may not get all the details right here, since I'm doing this from memory, but it goes something like this:

1. As a stand-alone Java Application in its own right, Tomcat's base classes are the core classes of any JVM. The JAVA_HOME or JRE_HOME environment variables anchor this.

2. When the catalina.bat/catalina.sh script runs to start (or stop!) Tomcat, part of the script does a sweep through the TOMCAT_HOME/lib directory and adds each jar in that directory to its classpath.

Incidentally, the Tomcat 7 catalina script BLANKS the original CLASSPATH environment variable before building its own internal version. So your environment classpath is ignored by Tomcat.

3. For each deployed webapp, an internal classpath is built consisting of the above paths plus all the classes in the WAR's WEB-INF/classes directory and all the JARs in the WAR's WEB-INF/lib directory.

Note that depending on what part of Tomcat or a Tomcat webapp you are executing in, the classpath may differ. That's what keeps libraries from one webapp from leaking into the other webapps.

There are several other internal classpaths, I think, but I can't remember them offhand.

I think you should migrate off Tomcat 5. I'm not sure that it's capable of resisting some of the nastier security exploits now prevalent.
 
J. Kevin Robbins
Bartender
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, very interesting info.

And we are in the process of migrating. I have the virtual machine file for our new web server. I plan to install it over the Christmas break and start testing. Java 8, Tomcat 8, MariaDB, all the fun toys...
 
Tim Holloway
Bartender
Posts: 18709
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
J. Kevin Robbins wrote:Thanks, very interesting info.

And we are in the process of migrating. I have the virtual machine file for our new web server. I plan to install it over the Christmas break and start testing. Java 8, Tomcat 8, MariaDB, all the fun toys...


If you're into Docker containers, I have an image that does all of the above except MariaDB (which is injected from a separate container). I think I even pre-loaded it with the Spring JPA weavers used by Hibernate JPA.

It's nice because I simply set up an external directory containing the WARs and external libraries (such as JDBC drivers) and launch the container with port 8080 remapped as required (so I can have multiple Tomcats with minimal fuss).
 
J. Kevin Robbins
Bartender
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I had to Google Docker Containers. Very interesting. One more thing to add to my already overloaded reading list.

I don't think there are enough years left in my life to read and learn all the things on my list.
 
Tim Holloway
Bartender
Posts: 18709
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have become somewhat of a container maniac. In fact, I've done a number of container projects for clients over the last 2 years give or take.

Very often when installing a new or upgraded software product, the first few go-rounds are flawed. The problem is, the act of installing the product "pollutes" the OS environment. Which is annoying at the best of times, but a lot of my career has been spent in putting together commercial products, so I have to install over and over again until I have my installer program(s) debugged.

In the Dark Ages, this was more or less a crap shoot, since I rarely had a spare machine (or the time) to completely wipe the hard drive to begin totally clean. VMs made that a lot easier, especially when products such as Vagrant came out and basically made the setup and provisioning of "throwaway" VMs basically a 1-button solution.

But VMs are still fairly substantial, since you are doing a from-scratch OS install and update in addition to whatever product you're working on. Containers take it to the next level. Instead of creating a whole new VM, containers share as many resources as possible, and only their differences are unique. So I can build a Docker image in a minute or 3, launch it and go. Plus, the surrounding paradigms are such that it's easier to manage external resources without having them lost in random corners of the hosting OS.

So these days I have a multi-tier environment:

1. Physical machines for physical infrastructure: cloud control, VM hosts, SAN-style storage and physical networking. Including the web reverse proxies to the containers/VMs.

2. Virtual machines for major subsystems. Two I have at the moment are one that has all my email services (sendmail, dovecot IMAP and Postman mailing list), one for my primary DBMSs, and one for source code/issue management (Trac and the Subversion archives)

3. Containers for the more nimble stuff. Things like Jenkins, Nexus, GOGS (a github clone), backend webapp servers, my file/disk backup server, stuff like that.

The other advantage of containers, incidentally, is that there are public appliance containers available, further extending the "plug and play" concept. The GOGS container I use, for example. And they're "subclassable", so that you can customize them incrementally.
 
AhFai Chan
Ranch Hand
Posts: 81
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Holloway wrote:I have become somewhat of a container maniac. In fact, I've done a number of container projects for clients over the last 2 years give or take.
...


I hope this is not veering too much off the main topic of where to put my CLASSPATH.

About 10 yeas ago, I installed Tomcat as my servlet container with classes that access 3 different database engines. Looking back, I thought it was not very helpful, it wasn't load balancing as I thought it would. Todate, I cannot see the benefit of Tomcat in a small environment.

Would it be better off just having different class files for different Oracle database instances with a servlet container e.g. one for HR, one for Finance, one for Accounting etc even if they are on the same database engine? Same goes for SQL Server.
 
AhFai Chan
Ranch Hand
Posts: 81
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Holloway wrote:
Despite all the abuse that Java has taken in the security arena in recent times, Java was, in fact, designed from Day 1 to be secure. One of the things that was done to ensure that security was that mechanisms exists to keep people from just dropping classes into the JRE's core classpath. Only resources that have been properly authorized will be recognized.


Actually you touched on the main and only reason I had for creating the CLASSPATH, JAVA_HOME etc as system env variables rather than user env variables.

Am I totally off track thinking that system env variables would give me better protection?

I nopticed that I have to run cmd as administrator to get a lot of work done, simple things like copying downloaded jars to their target directory.
 
Tim Holloway
Bartender
Posts: 18709
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fear not. If anyone wants to further discuss the virtues of containerization, we can spin that off to a more appropriate forum.

Tomcat is very good for "lightweight" usage - meaning that you don't need the full J2EE stack. I think you may be confusing classes with databases, however.

The stock Oracle JDBC driver jar (and its classes) can be shared between as many webapps - AND as many databases - as you like within a single Tomcat server instance.

Tomcat version 6 (5?) and later have a single common library for resources that multiple webapps can use. It contains the basic Tomcat container functions, but it can be augmented by any JAR you like, subject to the following restrictions:

1. Tomcat/lib jars MUST be thread-safe. Tomcat itself and the apps it runs run under multiple concurrent threads.

2. Tomcat/lib jars SHOULDN'T be app-specific. The idealized webapp is self-contained and not directly dependent on external classes except as defined by the J2EE standard. For example, my Tomcat servers typically have Spring support (AOP libaries) in them. They do not provide application logic services (stuff directly called by application program logic), although the applications may depend on the enhanced abilities that these libraries give the Tomcat runtime environment.

I don't know if it's formally spelled out in JDBC standards, but all of the JDBC drivers I know of meet these criteria. Furthermore, your webapps should be using J2EE Connection pools, instead of creating and destroying Connections within application code. Connection Pools are constructed and maintained by the Tomcat server, so it's essential that the neccesary classes (the JDBC driver) be located within Tomcat's lib directory, not inside any of the WARs.

I have done systems where a single app worked with 2 or more independent Oracle servers (not just databases, by completely different servers!). And apps when Oracle and MySQL databases were both employed by the same webapp. J2EE can handle such things, no worries.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!