JAVA ClassLoad same class name - java

Yesterday i thought one question ,below is the detail:
I have 3 JAR files, a.jar, b.jar ,c.jar . both these jars files have a class named com.test.Test ,and sayHello() was defined in this class.
I create a web application, i reference a.jar,b.jar,c.jar . And in main method, i involve sayHello(); .at this time, which com.test.Test will be load?
the result is a.jar.
any body tell me the reason ?? thanks in advance!!!

That is what java language specification says. It loads what ever the class first occurs in classpath and ignores other.

Instead of focusing on which one will be loaded, realize that the stuff within the JAR files probably need their com.test.Test class instead of someone else's com.test.Test to work properly. That means for a functional system you'll have to make a way that a.jar finds a.jar's com.test.Test instead of the one in b.jar. The same goes for b.jar finding it's classes in preference to a.jar's.
The only way to do this is to use a framework which adds name spacing beyond the java package mechanism. This is typically done with multiple classloaders, often one for each JAR file. You can write such a thing yourself (Tomcat did), where you need to specify the rules for cross-loader discovery, or use something akin to a OSGi framework.

Whichever Jar File comes first in your classpath will be used..
You can modify your CLASSPATH environment variable to the path of your Jar file
Suppose you modify it as below: -
set CLASSPATH = %CLASSPATH%;.;a.jar;b.jar
then a.jar will be used..
You can also modify it by: -
set CLASSPATH = %CLASSPATH%;.;b.jar;a.jar
In this case, b.jar will be used..
These commands you need to run from your Command Line..
** NOTE: - If you are using any IDE, then they don't use System Classpath.. You need to set different classpath for the IDE you are using..

If you are using an IDE, such as eclipse, you can modify your classpath on the properties of the project, then go to Build Path, and then you have the Order and Export tab where you can move up and down the jars. The one of the top will be the first taken by your application.
This you can also do manually by editing the file called "classpath" which is on your project and move to the top the jar you want your application to use first.

Related

Which jar file is used during compilation?

Let's assume I have two jar files on classpath when building my project - myJarFile.jar and myJarFileOld.jar. They contain the same packages and the same classes, but the myJarFileOld.jar contains old implementation, which causes that the compilation fails. I'm not asking for solution of this error, I know that I should remove myJarFileOld.jar to make compilation work. However I'd like to know, what mechanism decides which class from which jar file is used during compilation, when both jar files are present?
When a class needs to be loaded, all jar files in the classpath, in order, are scanned. As soon as the class is found, it's loaded.
Not fully sure, but I believe the order of classpath appearance is deciding. If it's found in first jar, then it's not search in another. However I'm pretty sure that class loader will load both jars at the beginning, and you will get some errors about duplicate code. However I'm not sure this, this is probably related to runtime environment.
you have this feature in Eclipse where you can specify the ordering of the jars that you want to be executed from the project classpath.Go to
Project->Select Properties->Select Build Path from left pane-> go to Order and Export Tab->Select Top or Bottom button-> click ok.
The next time you build your project the jar from the classpath will be picked in the order that you have specified.

Referencing wrong jar file in java build-path

In my project we are referencing lot of dependency .jar files.
/lib/xxx.jar
/lib/abc.jar
The xxx.jar file having some (com.search.hit) packages. The same packages are available in abc.jar file.But the problem comes into picture now, where accessing xxx.jar file it doesn't referencing their package(com.search.hit) instead it is referencing abc.jar package.
Could anyone tell how to redirect the flow?
The class from whichever jar comes first on the classpath is the one that is used. The other one might not even exist as far as the classloader is concerned. It's a good idea to avoid conflicts like this.
In Eclipse go to your project build path configuration and click on the Libraries tab.
Then remove the package that you don't want to be accessed from your list and add it again.
This will cause the package to be lower in the priority list and it'll check the other package before the one you just re-added.
This will create problems for you. My suggestion would be to create 2 extra classes for writing getter and setter wrappers for these jar files. Write 2 seperate classes, each one of them will reference just one of them and your project file will use these wrapper classes to invoke functions from these jars. It would be a lot easier that way.
You have to change the package name it can not be same file name with same package in single JVM. JVM will take load randomly one jar class using class loader and ignore the rest.

Including .jar files in a classpath

I'm trying to get JDBC up and running in the Windows environment. What does it mean to include a .jar file in the classpath? I see how to modify the CLASSPATH environment variable for Windows... But what files need to go where and what does the CLASSPATH environment variable need to be set to? I've tried just about every combination that I can immediately think of, and I'm at a loss.
Thanks.
The CLASSPATH variable contains a list of directories where class files are found. A .jar file is really a zipped up directory, so the name of the .jar file itself should be in the CLASSPATH, not the name of the directory it is in.
If, for example, you had two directories with class file trees in them C:\java\classes\ and C:\java\specialclasses\ and two jar files C:\java\jars\jam.jar and C:\java\jars\jelly.jar then your class path variable would be set to C:\java\classes\;C:\java\specialclasses\;C:\java\jars\jam.jar;C:\java\jars\jelly.jar
As a general rule, unless you have two packages with classes with the same name (which hopefully you don't), then you just want to add things that are going to commonly be used to the CLASSPATH variable and not remove or replace things which are already there. By default, it includes the directories of the java.* classes, which are kind of important to include. Also, depending on your environment, other commonly used classes may have been added by an administrator.
Look no further than Oracle's own documentation
For instance, if you had 3 jars in /a/directory, you would do something like:
java -classpath /a/directory/jar1.jar;/a/directory/jar2.jar;/a/directory/jar3.jar
You would set the CLASSPATH variable in a similar fashion.

Adding external .jar file in Eclipse

I'm having trouble adding a .jar file I downloaded for my Java project. This is really the first time I've used eclipse, so please bear with me and for some reason (I have no clue why), I just find it somewhat confusing.
I know that in order reference different class files you simply need to create a class library and add it to the build path. From there, all which needs to be done (unless I'm misunderstanding this for whatever reason) is use the "import" keyword to import whatever .jar, .java, or .class/.interface file necessary into the project.
I've tried that with my .jar. I have it referenced in the build path (all I did was just copy the jar to the project directory, and then use the build path option to add it externally), but when ever try to call the object "Delegator", which obviously is a part of the .jar file, it won't read.
Am I missing something here? Seriously, anyone who knows the answer to this - you're relieving a mother of a headache. And before anyone asks - yes, I've searched this one to death. I've found similar questions, but nothing which quite hit what I was looking for. Either that, or I really just lack the common sense.
Right click on project->BuildPath->Libraries->Addexternaljar and then press ok and if it doesnot worked then you should go to the Order and Export tab and checked the jar you have just added in your project. It will solved your problem.
There are several possible reasons, for the question hasn't mentioned the specific failure, and where it has occurred. The following is a list of possible reasons I could think of, but this may not be exhaustive:
You can import a class, in a different package only if the class is public. The only exception is when you are using the class in the same package. If the class is an inner class marked as private, then you're well and truly out of luck. The Delegator class in question might not be public, and that's why you may be unable to use it. This issue ought to be caught by the compiler.
The directory structure within the JAR might not match your package import statements in your classes. This might not be necessary, for Eclipse ought to provide possible fixes, but it is better to verify that nevertheless. Again, the compiler should complain if this is the case.
If the issue is at runtime, then, it is most likely that the JAR is not available in the runtime classpath. You'll need to configure the Runtime configuration, to add the JAR to the runtime classpath. Refer to the Eclipse documentation on run configurations, if you need to know how to change the runtime classpath.
Note:
Exporting the build classpath entries would matter to other projects that depend on the pertinent project; unexported entries will have to be re-imported if required in other projects. This would not apply to a run configuration.
Update
Every Java application needs a main(String[] args] method to start execution. This is the entrypoint for the application. From the comment, it appears that the main method is in a different class. If so, the said class ought to be used to start the application. In Eclipse, a "Run configuration" might be used for the class that lacks this entrypoint, resulting in the described error. One can rectify this by creating a new Run configuration for the class with the said entrypoint. This may be done by one of the following:
editing the existing Run configuration to use the desired Class (the one with the main method). See the above link, in the third bullet point. Edit the value of the class to be launched.
creating a new Run configuration for the desired Class. Usually, you'll need to traverse to the desired class, and run your application (using the Alt+Shift+X+J shortcut) from the said class.
i was facing similar issue with spring jar files but then tried with different jar files and it work so I think , classes defined in jar files were private and not available outside of jar hence you were not able to access the file .
thanks ,
Raju Rathi
Right click on the project--->Build Path--->Configure Build Path...--->In left side you have to choose Java Build Path--->Libraries--->Add External JARs--->ok--->ok
Steps to add jar file in eclipse
1. right click on project
2. click on Bulid Path->configure path
3. click on java Build path
4. Click on libraries tab
5. click on add external jar tab
6. choose jar file
7 click on ok
Copy the .jar file in libs folder which you want to add in your project.
Right click on .jar file -> Add Build Path
Done.

How should I set CLASSPATH?

I did this before:
CLASSPATH=".:/home/phoenies/jdk1.6.0_17/lib/tools.jar:/home/phoenies/jdk1.6.0_17/lib/dt.jar"
But today an article says I should do this:
CLASSPATH=".:/home/phoenies/jdk1.6.0_17/lib"
If I do so, will it search all the jar files in lib? So it's probably a shorter way?
Since you are using JDK6, you can use classpath wildcards: CLASSPATH=".:/home/phoenies/jdk1.6.0_17/lib/*" will match all JARS inside lib/
Check out http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html there's a section called "Understanding class path wildcards"
I think having a CLASSPATH environment variable is wrong for all but the easiest of "Hello, World" tutorials.
The right way is to set the CLASSPATH for every project when you compile and run. Every project is likely to be different, so this makes perfect sense.
IDEs ignore CLASSPATH environment settings; so do all Java EE app servers. It's a relic of Java 1.0. I don't have CLASSPATH set on any machine that I work on.
Learn to script it for the command line. Or use Ant. You'll be glad you did.
Yes, it will search all jar files in lib if you do it the second way. It's pretty odd to see class path being set as specifically as in the first one. I suppose on a server where you wanted to be sure what jars were being loaded, that might be one way to restrict them, but you might run into issues with how long it can be if you had several jars.
Jar files need to be specified by name in the Classpath variable. One thing to note is that the commandline -classpath param is more versatile than the environment variable, as it allows you to set a classpath per application.
In Java 1.6+ you can set the classpath to a directory followed by /* to load all JAR files in that directory. Not just the directory name though - that's for loading class files in that directory and subdirectories.

Categories