I have a jar called "MyTools". The jar is in c:\data folder. I created a new file in the same folder called "UseTools.java". Now I would like to use some of the classes from the MyTools.jar in my UseTools.java. I tried this but it doesnt seem to work:
import MyTools.*;
public class UseTools
{
public static void main(String[] args)
{
MyTools.SomeClass foo = new SomeClass();
SomeClass.doSomething();
}
}
I tried to compile this with:
javac -cp . UseTools.java
and got this error message:
UseTools.java:1: package MyTools does not exist
import MyTools.*;
^
UseTools.java:7: package MyTools does not exist
MyTools.SomeClass foo = new SomeClass()
^
2 errors
I did not set the package name in any class.
Do I have to set a package name in my jar classes?
To mention something that relates more to the title of the question:
In Java, you can't access classes in the default package from code within a named package.
This means, if the classes in your jar file do not belong explicitly to any package and inside the jar your files are directly in the root folder without subfolders, they are in the default package. This is not very elaborated and lacks modularity as well as extensibility, but is technically alright.
Then, you can only use these classes from code which also is in the default package. But this does not necessarily mean it has to be in the same jar. If you have multiple src or class folders they could all contain classes in the default package which can interact. The organization in JAR files and the package structure in your project are independent of each other.
However, I'd strictly encourage you to use explicit package information.
In your MyTools.jar there should be a package with the name MyTools. And before compiling you should add the jar to the classpath.
You need to add -cp file.jar instead of -cp .
The latter one will pick up .class files only. BTW: why not using an IDE like netbeans, eclipse or intelliJ?
Related
I have two classes:
MyApplication Library
The Library has already been compiled into Library.class and the source code is no longer available. I am now trying to compile MyApplication from source. MyApplication depends on the Library. The Library has a package name of org.myCompany. I tried setting my classpath to the following:
set CLASSPATH=C:\java\project\org\myCompany\Library.class;.
which produced the following javac compiler error message:
MyApplication.java:33: cannot find symbol
symbol: class Library
location: class MyApplication
Library theLibrary = new Library();
So I changed my classpath to be:
set CLASSPATH=C:\java\project\;.
which produced the exact same error message.
How do I set my Windows classpath to include the Library.class file? Should it point at the folder contains the org\myCompany subfolders? Or point directly to the class file? Or to the folder containing the class file (even though the class is in a package and belongs in a subfolder)?
I do an echo %CLASSPATH% after my set command and the classpath is being set correctly. I also made an ant build.xml file and encountered the same problem. In fact, ant -verbose confirmed that my classpath is being set correctly.
First of all: the use of the CLASSPATH environment variable is very strongly discouraged. The best thing is for you to forget that it exists. Use the -cp command line switch or similar methods to set the classpath.
Second, the classpath entries each represent a place where the classloader will start looking for .class according to the package hierarchy, i.e. it will look for the class org.myCompany.Library in a subfolder org/myCompany in any of the classpath entries.
Therefore, if
you add a classpath entry C:\java\project\
and there is a class file C:\java\project\org\myCompany\Library.class
which is actually part of a package org.myCompany (capitalization matters here!)
and your MyApplication class has an import org.myCompany.Library;
Then it really should work.
You cannot add a single class in your classpath like this. You have 3 solutions:
add this class in the path of your other compiled classes (respecting the package naming of your directories)
add the root directory of this class in your classpath (in your case "C:\java\project\")
add this single class into a jar and add this jar to the classpath
For your problem, the thrird choice is cleaner: external dependencies normally are packaged into jar files.
If your .class file isn't in jar file, point your classpath to the parent dir where package of class resides, e.g., for class org.myCompany.Library, point your CP to directory containing org/myCompany.
If your .class file included into some jar file, add full path to that jar to your classpath.
If you compiled the class files to a different directory, the classpath needs to point to where the .class file is.
set CLASSPATH=C:\java\project\;
is correct assuming that that the class file is in the same directory as the .java source file.
Is there a problem locating the Library to the same root project where is your MyApplication class
Example, if:
c:/project/org/company/MyApplication.class
Can you locate the Library class into:
C:/project/org/myCompany/Library.class
please notice, that the folders org/myCompany and org/company are located under the same folder c:/project/.
Please notices that this solution works for you if the Library Class is only used by your application.
Edited
Windows command prompt is tedious, after setting the classpath please close and re-open the Command Prompt, so it can see the new classpath's value.
For the classpath to work, you need to have a folder structure which matches the package hierarchy. So if your class is org.myCompany.Library, you must create a nested folder structure of C:\java\project\org\myCompany and place your Library class file in the myCompany folder. Then set the class path to C:\java\project\
There is a class a.b.c.Hello of which I would just get the Hello.class file delivered. I would like to run using something like:
java Hello
//or
java a.b.c.Hello
This leads me to a NoClassDefFoundError. Normally I'd have the a/b/c dirs with the class insdie and I'd add them to the -classpath option, but:
Is there a way of running a class in a package like this without having to put it inside a/b/c to match the package name?
All solutions I've found state the directory structure has to match the package naming, but I'd like to run the .class file directly from the folder where it is without recreating the folder structure
Is there a way of running a class in a package like this without having to put it inside a/b/c to match the package name?
Yes: By using a jar. Put the .class file in the jar (with the correct path), and then:
java -cp TheJarFile.jar a.b.c.Hello
This is, of course, very much like putting it in an a/b/c directory; it's just that the directory is in the jar, not the file system.
The packages do not just structure your classes (in folders), they also create a namespace. While the simple class name is Hello, the real class name is a.b.c.Hello.
That's because class names might repeat frequently (in different libs, f.e), but must be addressable on the other hand. For example: 'User', 'Logger', 'List', 'Date'.
Its not recommended, but you can put your class in the default package, too. Just remove the 'package ...' line.
I'm a C++ developer - not a java developer, but have to get this code working...
I have 2 public classes that will be used by another product. I used the package directive in each of the java files.
package com.company.thing;
class MyClass ...
When I try to compile a test app that uses that I add
import com.company.thing.*;
The javac compiler fails with errors about com.company does not exist. (even if I compile it in the same directory as the class files I just made a package of)
I am sure I am doing something bone-headed and silly.
I've read the http://java.sun.com/docs/books/tutorial/java/package/usepkgs.html pages and tried to set up a directory structure like /com/company/thing etc, but either I have totally screwed it all up or am missing something else.
EDIT
thanks for the suggestions - I had tried the classpath previously. It does not help.
I tried compiling
javac -classpath <parent> client.java
and the result is:
package com.company does not exist
I have the code I want to import (the two java files) in \com\company\product. I compile those fine. (they contain MyClass) I even made a jar file for them. I copied the jar file up to the parent directory.
I then did (in the parent directory with the client java file)
javac -cp <jarfile> *.java
the result is:
cannot access MyClass
bad class file: MyClass.class(:MyClass.class)
class file contains wrong class: com.company.product.MyClass
Please remove or make sure it appears in the correct subdirectory of the classpath.
EDIT
I got the client code to compile and run if I used the fully qualified name for MyClass and compiled it in the parent directory. I am totally confused now.
compiled with no classpath set - just
javac *.java
in the parent directory - and it worked fine.
I can get a test app to compile, but that is not going to cut it when i have to integrate it into the production code. Still looking for help.
EDIT:
Finally - not sure why it didn't work before - but I cleaned up all the files all over the directory structure and now it works.
Thanks
Okay, just to clarify things that have already been posted.
You should have the directory com, containing the directory company, containing the directory example, containing the file MyClass.java.
From the folder containing com, run:
$ javac com\company\example\MyClass.java
Then:
$ java com.company.example.MyClass
Hello from MyClass!
These must both be done from the root of the source tree. Otherwise, javac and java won't be able to find any other packages (in fact, java wouldn't even be able to run MyClass).
A short example
I created the folders "testpackage" and "testpackage2". Inside testpackage, I created TestPackageClass.java containing the following code:
package testpackage;
import testpackage2.MyClass;
public class TestPackageClass {
public static void main(String[] args) {
System.out.println("Hello from testpackage.TestPackageClass!");
System.out.println("Now accessing " + MyClass.NAME);
}
}
Inside testpackage2, I created MyClass.java containing the following code:
package testpackage2;
public class MyClass {
public static String NAME = "testpackage2.MyClass";
}
From the directory containing the two new folders, I ran:
C:\examples>javac testpackage\*.java
C:\examples>javac testpackage2\*.java
Then:
C:\examples>java testpackage.TestPackageClass
Hello from testpackage.TestPackageClass!
Now accessing testpackage2.MyClass
Does that make things any clearer?
Yes, this is a classpath issue. You need to tell the compiler and runtime that the directory where your .class files live is part of the CLASSPATH. The directory that you need to add is the parent of the "com" directory at the start of your package structure.
You do this using the -classpath argument for both javac.exe and java.exe.
Should also ask how the 3rd party classes you're using are packaged. If they're in a JAR, and I'd recommend that you have them in one, you add the .jar file to the classpath:
java -classpath .;company.jar foo.bar.baz.YourClass
Google for "Java classpath". It'll find links like this.
One more thing: "import" isn't loading classes. All it does it save you typing. When you include an import statement, you don't have to use the fully-resolved class name in your code - you can type "Foo" instead of "com.company.thing.Foo". That's all it's doing.
It sounds like you are on the right track with your directory structure. When you compile the dependent code, specify the -classpath argument of javac. Use the parent directory of the com directory, where com, in turn, contains company/thing/YourClass.class
So, when you do this:
javac -classpath <parent> client.java
The <parent> should be referring to the parent of com. If you are in com, it would be ../.
You got a bunch of good answers, so I'll just throw out a suggestion. If you are going to be working on this project for more than 2 days, download eclipse or netbeans and build your project in there.
If you are not normally a java programmer, then the help it will give you will be invaluable.
It's not worth the 1/2 hour download/install if you are only spending 2 hours on it.
Both have hotkeys/menu items to "Fix imports", with this you should never have to worry about imports again.
The standard Java classloader is a stickler for directory structure. Each entry in the classpath is a directory or jar file (or zip file, really), which it then searches for the given class file. For example, if your classpath is ".;my.jar", it will search for com.example.Foo in the following locations:
./com/example/
my.jar:/com/example/
That is, it will look in the subdirectory that has the 'modified name' of the package, where '.' is replaced with the file separator.
Also, it is noteworthy that you cannot nest .jar files.
Just add classpath entry ( I mean your parent directory location) under System Variables and User Variables menu ...
Follow : Right Click My Computer>Properties>Advanced>Environment Variables
I'm working on creating my own implementation of one of the system Java packages but am having some problems with the wrong class getting picked up when trying to use the package.
For example, lets say my package is: a.b.c.DoStuff and there is an existing Java package with the exact same name, a.b.c.DoStuff.
Using the following code in a test application, I can tell that the system class is still getting used (located in /usr/lib/jvm/java-6-openjdk/jre/lib/rt.jar) instead of my own:
ClassLoader loader = test.class.getClassLoader();
System.out.println(loader.getResource("a.b.c.DoStuff.class");
My package has been compiled into a jar file (package.jar), and I have:
Imported the class in my test file (import a.b.c.DoStuff;)
Added package.jar to my classpath (with both "export CLASSPATH..." and using "java -classpath...")
There must be something I'm overlooking? Any thoughts on how to get my package picked up instead of the system package?
Thanks,
Chris
You can't replace classes from the standard packages unless you put your jar in the special 'endorsed' directory. And some you can't replace at all that way.
Thanks, bmargulies for the tip on the bootclasspath! Prepending my .jar file to the bootclasspath solved my problem. To summarize, I was able to use my own Java package implementation by prepending my package's .jar to the bootclasspath:
java -Xbootclasspath/p:<path-to-jar>
Basically I wish to use the methods of a class within the Jar file, which looks like this:
Can somebody please tell me what I need to import in order to use those methods and variables?
You don't need to import anything.
Jar files aren't imported, they are added to the classpath.
From the screenshot you've posted, we can see that the myJar.jar file is included in your eclipse classpath, so there's nothing more to do there.
Classes are imported, if they are in a different package.
Your Examplew class is in the default package. BMIcalculator is also in the default package. Because they are the same package, you don't need to import it.
You should be able to simply make references to BMIcalculator from within Examplew. Just try it.
Try compiling this code - it should work:
public class Examplew
{
private BMIcalculator calc = new BMIcalculator();
}
You might get warnings about the unused private field, but you can ignore that for now.
If that doesn't work for you, then please post the error, because it doesn't look like the problem is with your imports (or your classpath)
Quote from this question:
You can’t use classes in the default package from a named package.
Prior to J2SE 1.4 you could import classes from the default package using a syntax like this:
import Unfinished;
That's no longer allowed. So to access a default package class from within a packaged class requires moving the default package class into a package of its own.
If you have access to the source generated by groovy, some post-processing is needed to move the file into a dedicated package and add this "package" directive at its beginning.