Java: class resolved? - java

I hope this question is not repeated. But just can't find answer anywhere:
I have ONE folder containing two files one A.java another B.class.
Now in A.java I am trying to declare
public class A extends Applet{
...
B aB;
}
The compiler gives me:
B cannot be resolved to a type
I read a lot of posts that say if the files are in the same folder, I don't need to import. Could anyone help me to "resolve" this problem?
Thanks much appreciated!
-----------SOLVED! - SEE ANSWER BELOW------------------

The .class files need to reside in a directory referenced by the classpath variable. Usually you put your .java files in one directory (src), compile to another directory (bin) and have external .class files in a third directory (lib). The commands will look like this:
# compile
javac -sourcepath src -classpath lib -d bin
# run
java -classpath bin:lib A
Using an IDE like eclipse should help a lot here as it takes care of most of the details

The simple case that you've posted works for me. I'd check the following things:
Are you sure that B.class is present in the same folder as A.java?
Are you running javac from that folder?
Have you typed the class name B correctly everywhere in your program? This includes capitalization, as Java identifiers are case sensitive.
Are there any package declarations in your program? If there are, none of this is going to work, since you're implicitly using the default package by just throwing everything into a folder.

The compiler looks for *.class file in its class path. It will only look for *.java files in the same source directories. You need to set the class path to include the directory.
Or you could use an IDE which sets all this up for you and saves a lot time in the process.

Related

bad class file using javac

Some background: I'm a student just learning Java, and usually the professor handles making sure our assignments have the right class path. However, the whole semester I've been plagued by the same problem, and I still don't understand what's going wrong.
As an example, I have two files, MyProgram.java located in the folder "MyProject" and MyProgramTest.java located in the folder "ClassProject", which also contains "MyProject". MyProgramTest creates a MyProgram object and lets you test its functionality.
MyProgramTest has the line import MyProject.MyProgram; The compiling instructions my instructor gives is to use javac MyProject/*.java while in "ClassProject" which works fine. Then, we are to use javac MyProgramTest.java in the same directory. However, the compiler claims:
import MyProject.MyProgram;
bad class file: .\MyProject\MyProgram.class
class file contains wrong class: MyProgram
Please remove or make sure it appears in the correct subdirectory of the classpath.
So I don't quite understand why this is happening. MyProgram is in the MyProject directory, and that directory is in the folder I'm in. Since the instructor uses this exact method to compile these programs, I keep getting screwed since mine never compile correctly. Any idea what I'm doing wrong, or how I can fix the file to compile this way without changing the structure of the directories?
Ensure this:
The MyProgram.java file should contain this line at the top of the file:
package MyProject;
Compile MyProgram.java from the ClassProject folder:
javac -d . MyProject/*.java
Then Compile MyProgramTest.java from the same folder:
javac MyProgramTest.java
This will create the class files correctly in the appropriate folder structure.
This should solve your problem.
Hope this helps!

Why does android studio does not recognize the "package net.simplifiedcoding.spacefighter;" code? [duplicate]

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

CLASSPATH 101... (on Windows)

I'm new to working with Java from the command line and I don't get it. I read previous CLASSPATH questions but still didn't get my problem to work.
I have the following class in C:\Temp\a\b\c
package a.b.c;
public class Hello
{
public static void main(String args[])
{
System.out.println("Hello World!");
}
}
The package name is intentional.
I compiled it fine and I put the Hello.class file inside C:\Temp\a\target
Now in the command line I go to C:\Temp\ and execute the following:
java -cp .\a\target a.b.c.Hello
It complains that it cannot find the class a.b.c.Hello
Thanks in advance!!
and I put the Hello.class file inside C:\Temp\a\target
This is wrong. It should be placed in the same folder as the .java file. The source code itself is declared to be in the package a.b.c; so, the .class file should really be kept in \a\b\c folder.
Then, to execute it just do:
C:\Temp>java -cp . a.b.c.Hello
Avoid "putting" the classfiles anywhere. The following should work:
javac -d c:\temp c:\temp\a\b\c\Hello.java
# creates Hello.class in c:\temp\a\b\c
java -cp c:\temp a.b.c.Hello
To expand on BalusC's point: the classpath defines a "root". When java is looking for your classes, it will start at each root (or jar) in your class path and drill down through the directories to match the package strucutre. You still need to have you class in a directory structure that matches its package name. In your case, to execute
java -cp .\a\target a.b.c.Hello
you would move the file to
.\a\target\a\b\c\Hello.class
Years ago, I too found this baffling.
Java will try to search for a directory structure a\b\c from starting in target and as you notice, it wont work.
Move the whole directory into target and you'll be fine, it should look like:
C:\Temp\a\target\a\b\c\Hello.class
You may compile it with the -d option which tall the compiler where to put the class file.
Many project structures are like this.
C:\whatever\projectname\src
C:\whatever\projectname\classes
C:\whatever\projectname\bin
C:\whatever\projectname\lib
C:\whatever\projectname\doc
That way you can always step on your project directory and type:
javac -d classes src\*.java
Which will compile all the sources in the src directory and will place them in the classes directory.
Then execute your program:
java -cp classes a.b.c.Hello
You may optionally place required jars in lib
This works pretty fine for small programs ( < 10 src files and 2 - 3 jar libraries ) If it grows beyond that, you could probably use an IDE or ant
The good thing about following this project structure is that some IDES ( as IntellJ idea ) just pick them very easily when you create a new project. You select "Create project from existing sources" and then you can continue from there.
I like compiling and editing at the command line a lot!!

Java not compiling .class files under $CLASSPATH

I'm trying to figure out how organize source and class files working with packages. I found a very useful tutorial. But I still have some questions.
As far as I understood it is a good practice to have an isomorphism between name of packages and name of the directories where elements of a package are stored. For example if I have a package named aaa.bbb.ccc which contains class ddd it is a good practice to have a class file called "ddd.class" and located in "$CLASSPATH/aaa/bbb/ccc/". Did I get it right?
If it is the case, will Java compiler put *.class files into the correct directory automatically?
I was not able to get this behavior. I set the $CLASSPATH variable to "/home/myname/java/classes". I executed javac KeyEventDemo.java which contains package events;. I expected that javac will create a subdirectory events under /home/myname/java/classes and put the KeyEventDemo.class in this subdirectory.
It did not happen. I tried to help to javac and created "events" subdirectory by myself. I used javac again but it does not want to put class files under "/home/myname/java/classes/events". What am I doing wrong?
You need to use the -d option to specify where you want the .class files to end up. Just specify the base directory; javac will create any directories necessary to correspond to the right package.
Example (based on your question):
javac -d ~/java/classes KeyEventDemo.java
For example if I have a package named
"aaa.bbb.ccc" which contains class
"ddd" it is a good practice to have a
class file called "ddd.class" and
located in "$CLASSPATH/aaa/bbb/ccc/".
Did I get it right?
That's not "good practice" - this is how the Sun JDK expects things to be. Otherwise, it will not work. Theoretically, other Java implementations could work differently, but I don't know any that do.
If it is the case, will Java compiler
put *.class file into a correct
directory automatically?
Yes
What am I doing wrong?
The source code must also already follow this structure, i.e. KeyEventDemo.java must reside in a subdirectory named "events". Then you do "javac events/KeyEventDemo.java", and it should work.
It is not only good practice but a must in most cases.
consider a Java class named:
com.example.Hello
If you store it on the filesystem, it has to got to
/path/to/my/classes/com/example/Hello.java
The compiler (or at least the vast majority) will create the class file at
/path/to/my/classes/com/example/Hello.class
Personally I would not use the CLASSPATH variable to set the path but the -cp option on java. A call to the above "application" could be done with:
java -cp /path/to/my/classes com.example.Hello

Re-compile a Java Class from Jar

I have an executable jar that has one class file with a wrong value. I requested that file from the author and corrected the value.
Now I want to compile it and add the compiled class file into the jar and run it.
Not surprisingly I get multiple "cannot find symbol" errors for references of custom object that were in the jar file.
I tried to compile the file by referencing the jar file in the classpath like so
C:/> javac file.java -classpath C:/folder/where/jar/is
but this doesnt seem to work... I get the same errors as if just doing
C:/> javac file.java
Is there a way to compile this individual class somehow referencing the other files in the jar?
Thanks.
Errors I am getting while following some of the suggestions below here:
javac -classpath C:/jar/location.jar File.java
File.java:226: cannot find symbol
symbol : class Stuff
location: class com.shared.stuffers
Stuff s1 = new Stuff();
^
Stuff class is found in the Jar, but can not be seen by the javac program... I feel like I am doing something wrong but not sure where? Thanks.
You will want to compile your file like so:
javac -classpath C:\folder\where\jar\is\the_jar_file.jar file.java
per the javac usage instructions:
C:\Console2>javac -help
Usage: javac <options> <source files>
Once you've compiled the new file (such as in Mr. Will's answer), you can add the new file to the jar using:
jar uf C:\folder\where\jar\is\the_jar_file.jar file.class
You probably have to specify the JAR file itself and not just the directory it resides in.
javac file.java -classpath C:\folder\where\jar\is\the_jar_file.jar
I'm just guessing, but did you check whether it doesn't need any external jar libraries you may have to include in your compilation command? Another thing you could do is to compile all of the classes by doing something like
javac *.java ...
As others have mentioned, once you have the .class file recompiled you need to replace the older version in the .jar
You'll likely need to have any compile time dependencies available to rebuild this class. If it's an open source project this could be an easy thing to come up with. If not, it's more difficult. If the author sent you the file he can probably help you with this as well. You might be able to get the author to produce a patched distribution for you as well. Odds are he/she already has the build environment set up and this should be relatively easy to do.
I'd try this approach (and it should work, unless the 'debugged' class doesn't introduce a new error):
create a new jar by taking the old
one and deleting the classfile that
you want to replace
compile the
corrected java file and make sure
that the modified jar is on the
classpath
add the newly compiled
classfile to the jar
This should work. If not - ask the author for a new complete library.

Categories

Resources