This seems like a simple problem, but somehow I'm having issues with this code. I'm getting back into Java after a few years, and I'm making a 2D game. In it, I have a main driver class called SnakeGame that loads a new instance of the class GameBoard.
SnakeGame.java
package snake2;
import javax.swing.JFrame;
public class SnakeGame extends JFrame {
public SnakeGame() {
add(new GameBoard());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(320, 340);
setLocationRelativeTo(null);
setTitle("Snake Game");
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new SnakeGame();
}
}
In the same directory lies GameBoard.java, which has a constructer with no required parameters:
public GameBoard() {
[... more code ...]
}
Edit
Both GameBoard.java and SnakeGame.java have package snake2; at the first line of their files.
However, I keep receiving the following error:
SnakeGame.java:7: cannot find symbol
symbol : class GameBoard
location: class snake2.SnakeGame
add(new GameBoard());
^
1 error
Edit #2
I've tried to add it to my class path, using java -cp . GameBoard after javac. Here's the first line of the terminal's scary looking and unnecessarily verbose response:
Exception in thread "main" java.lang.NoClassDefFoundError: GameBoard (wrong name: snake2/GameBoard)
This is as if I've misspelled the class, or misspelled a file name. Although, to my knowledge, I haven't done either. Is there some other problem with my code that I haven't noticed?
Thanks for any help in advance.
Besides being in the same directory, do you have a package statement in GameBoard.java?
Edit for running the program --
#Stephen: I'm running java, and all the files are in the same directory.
From #kbolino
You must put your source files in a snake2 directory and run javac from the parent directory [...]
You must also invoke java, not just javac, with the correct package and classpath.
Examples that worked for me, after creating SnakeGame and GameBoard stubs:
Current dir is projects which is the parent of the snake2 dir where the files are:
java snake2.SnakeGame
Current dir is snake2 where I was editing the files:
java -cp .. snake2.SnakeGame
For case #2 since you're in the package dir you have to put the parent dir in the classpath.
.
Adding a ridiculous amount of information showing my session with both the javac compile command and java run. You don't need -cp for compiling as suggested by some.
[~/tests/java/snake2]$ pwd
/home/stephenp/tests/java/snake2
[~/tests/java/snake2]$ cat GameBoard.java
package snake2;
class GameBoard {
private static int instanceCount = 0;
GameBoard() {
GameBoard.instanceCount++;
}
void howMany() {
System.out.println(instanceCount + " GameBoards have been created.");
}
}
[~/tests/java/snake2]$ cat SnakeGame.java
package snake2;
public class SnakeGame {
private GameBoard board = null;
public SnakeGame() {
this.board = new GameBoard();
}
void report(String msg) {
System.out.println(msg);
}
public static void main(String[] args) {
SnakeGame game = new SnakeGame();
game.report("I exist");
game.board.howMany();
}
}
[~/tests/java/snake2]$ ls -1
GameBoard.java
SnakeGame.java
[~/tests/java/snake2]$ javac *.java
[~/tests/java/snake2]$ ls -1
GameBoard.class
GameBoard.java
SnakeGame.class
SnakeGame.java
[~/tests/java/snake2]$ java SnakeGame
Exception in thread "main" java.lang.NoClassDefFoundError: SnakeGame (wrong name: snake2/SnakeGame)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
[~/tests/java/snake2]$ java snake2.SnakeGame
Exception in thread "main" java.lang.NoClassDefFoundError: snake2/SnakeGame
Caused by: java.lang.ClassNotFoundException: snake2.SnakeGame
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
[~/tests/java/snake2]$ java -cp .. snake2.SnakeGame
I exist
1 GameBoards have been created.
Packaging
Package up your application in a .jar file along with a Manifest that specifies the main class to run, then you can run your program just using
java -jar myprogram.jar
To do that, create a file Manifest.txt in the directory above your package directory
[~/tests/java/snake2]$ cd ..
[~/tests/java]$ ls -1F
Manifest.txt
snake2/
[~/tests/java]$ cat Manifest.txt
Main-Class: snake2.SnakeGame
[~/tests/java]$ jar cfm myprogram.jar Manifest.txt snake2/*.class
[~/tests/java]$ jar tf myprogram.jar
META-INF/
META-INF/MANIFEST.MF
snake2/GameBoard.class
snake2/SnakeGame.class
You can also wrap a script (shell script, batch file, etc.) around that so you just run myprogram and it runs java -jar myprogram.jar
This would all be part of your build process.
I don't really know if it is your problem. But in the API from JAVA, if you search for JFrame, in the description says something like this:
The JFrame class is slightly incompatible with Frame. Like all other JFC/Swing top-level containers, a JFrame contains a JRootPane as its only child. The content pane provided by the root pane should, as a rule, contain all the non-menu components displayed by the JFrame. This is different from the AWT Frame case. For example, to add a child to an AWT frame you'd write:
frame.add(child);
However using JFrame you need to add the child to the JFrame's content pane instead:
frame.getContentPane().add(child);
Could you try it?
The GameBoard that you want to add to your JFrame SnakeGame must inherit from java.awt.Container, e.g. JPanel.
Moreover, your code creates two GameBoard instances, one for the print, and one for the add method. It would be more efficient if you've created a variable:
GameBoard gameBoard = new GameBoard();
System.out.println(gameBoard);
add(gameBoard );
In your case, The GameBoard instance you print and the instance you add to the JFrame are two different ones.
You must put your source files in a snake2 directory and run javac from the parent directory with the following invocation:
javac snake2/*.java
In general, your directory structure must correspond to your package names.
Possibilities:
Non-printing and/or special characters snuck into one of your files and makes the GameBoard identifiers different even though they look the same
One or more of your files has character encoding issues that are tripping up the compiler
GameBoard does not inherit from java.awt.Component, which is necessary for add() to work
You omitted the public modifier in front of class GameBoard
You omitted the package snake2 statement at the top of GameBoard.java
This page lists some common causes of the "cannot find symbol" error, although it may not explain your particular error.
EDIT :
kbolino may be onto something, although his answer was syntactically incorrect. I made a mockup on my machine, and the following works for me:
(any parent directories)
|
|--snake2
|
|--SnakeGame.java
|--GameBoard.java
and then running, from inside the snake2 directory,
javac SnakeGame.java GameBoard.java
followed by returning to snake2's parent directory and running
java snake2/SnakeGame
EDIT 2
In a comment, the OP asked "how come java SnakeGame doesn't work within the snake2 folder, but java snake2/SnakeGame works in the parent directory?"
The question is well-meaning, but misleading. snake2 in that command is part of the name, not a path. If you are in the snake2 folder, java -cp .. snake2/SnakeGame still works. For similar reasons, javac -cp snake2 snake2/SnakeGame.java snake2/GameBoard.java also works when you are in snake2's parent directory.
That said, java snake2/SnakeGame alone (still from inside the snake2 folder) does not work. This is because
Remember when using a classpath, the last directory in the path must be the super-directory of the root directory for the package. (SCJP 6 guide, Sierra & Bates, p804)
Check the classpath. Usually when I run into problems like this it is a classpath problem. I know your situation isn't to complicated but check anyways.
Also, if you are using eclipse, try cleaning your workspace. Sometimes weird quirks like this are worked out through that.
The only issue I can think of is if the package in GameBoard is not defined properly. Or, have you tried clean and recompile all?
It is funny what potential such a trivial problem has with experienced Java developers.
I assume you are not using any IDE and write your classes in some text editor and compile them nicely from command line using javac, are you not?:)
You obviously miss . (dot, a symbol for the current folder) from your CLASSPATH. Either set CLASSPATH as a system variable or use following with javac:
javac -cp . SnakeGame
Are you using command line?
have you complied GameBoard first?
you should try
javac *.java
from your "snake2" directory
Edit: after this move one level up (cd..) the run
java snake2/SnakeGame
Related
I wrote a java program to test RESTful web services by using Netbeans7.0.1 and it works fine there. Now I wrote the build.xml file to compile the code and when I try to run the generated .class file I always got this exception:
Exception in thread "main" java.lang.NoClassDefFoundError: ClientREST (wrong name: clientrest/ClientREST)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: ClientREST. Program will exit.
The name and path are correct, so any thoughts why I'm getting this exception?
Exception in thread "main" java.lang.NoClassDefFoundError: ClientREST
So, you ran it as java ClientREST. It's expecting a ClientREST.class without any package.
(wrong name: clientrest/ClientREST)
Hey, the class is trying to tell you that it has a package clientrest;. You need to run it from the package root on. Go one folder up so that you're in the folder which in turn contains the clientrest folder representing the package and then execute java clientrest.ClientREST.
You should not go inside the clientrest package folder and execute java ClientREST.
I encountered this error using command line java:
java -cp stuff/src/mypackage Test
where Test.java resides in the package mypackage.
Instead, you need to set the classpath -cp to the base folder, in this case, src, then prepend the package to the file name.
So it will end up looking like this:
java -cp stuff/src mypackage.Test
To further note on Garry's reply: The class path is the base directory where the class itself resides. So if the class file is here -
/home/person/javastuff/classes/package1/subpackage/javaThing.class
You would need to reference the class path as follows:
/home/person/javastuff/classes
So to run from the command line, the full command would be -
java -cp /home/person/javastuff/classes package1/subpackage/javaThing
i.e. the template for the above is
java_executable -cp classpath the_class_itself_within_the_class_path
That's how I finally got mine to work without having the class path in the environment
Probably the location you are generating your classes in doesnt exists on the class path. While running use the jvm arg -verbose while running and check the log whether the class is being loaded or not.
The output will also give you clue as to where the clasess are being loaded from, make sure that your class files are present in that location.
Try the below syntax:
Suppose java File resides here: fm/src/com/gsd/FileName.java
So you can run using the below syntax:
(Make current directory to 'fm')
java src.com.gsd.FileName
Suppose you have class A
and a class B
public class A{
public static void main(String[] args){
....
.....
//creating classB object
new classB();
}
}
class B{
}
this issue can be resolved by moving class B inside of class A and using static keyword
public class A{
public static void main(String[] args){
....
.....
//creating class B
new classB();
static class B{
}
}
Here is my class structure
package org.handson.basics;
public class WithoutMain {
public static void main() {
System.out.println("With main()...");
}
}
To compile this program, I had to use absolute path. So from src/main/java I ran:
javac org/handson/basics/WithoutMain.java
Initially I tried with the below command from basics folder and it didn't work
basics % java WithoutMain
Error: Could not find or load main class WithoutMain
Caused by: java.lang.NoClassDefFoundError: org/handson/basics/WithoutMain (wrong name: WithoutMain)
Later I went back to src\main\java folder and ran the class with relevant package structure, which worked as expected.
java % java org.handson.basics.WithoutMain
With main()...
I also have encountered this error on Windows when using Class.forName() where the class name I use is correct except for case.
My guess is that Java is able to find the file at the path (because Windows paths are case-insensitive) but the parsed class's name does not match the name given to Class.forName().
Fixing the case in the class name argument fixed the error.
I am using Netbeans 8.1 and Java 8.
I have a Java program named "MyFrame.java" and I want to create a package with its classes and methods - I call this package "myframe" and it is located at "\Lab\MyFrame\src\myframe". See picture:
(Ignore the red lines - this is a dummy version).
The class file is created after compiling, using the command "javac MyFrame.java", in the same directory \myframe. Now I want to import the package "myframe" in a new Java file "MoreButtons.java". So it would look like this and for convenience I save it in \src:
Compiling and executing MoreButtons.java works fine. The package has been imported. But now MyFrame.java is a bit trickier to execute: the naïve approach yields:
Translation: Error: Could not find or load main class
This seems to be quite a common problem and one of the solutions is simply to add the directory (\myframe) to the PATH environment variable. However, doing this still produced the error.
1) What am I doing wrong and how can I fix this?
2) What is the correct way to create and import custom-made packages in Java?
Make sure that terminal is at path Lab\MyFrame\src:
javac myframe\MyFrame.java MoreButtons.java
java -cp .; myframe.MyFrame
P.S. (/,:=linux/mac) or (\,;=windows)
MyFrame.java
package myframe;
public class MyFrame extends javax.swing.JFrame{
public MyFrame(String title){
super(title);
setSize(200,100);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
}
MoreButtons.java
public class MoreButtons {
public static void main(String[]args){
new myframe.MyFrame("More Buttons");
}
}
I'm a relative Java newbie so apologies if the question appears somewhat basic. I've googled high and low for an answer here and I'm not finding anything that's helping.
Problem:
Whilst I'm able to integrate external packages into my Java programs from an IDE environment, I am trying to do run a very basic program from the command line that calls on a separate, basic package file that I have written - and am simply doing all this as I want to have a bottom-up understanding of how package files are related to a main program by Java.
I have a program that sits on my desktop named MyProgram.java:
import org.somepackage;
public class MyProgram {
public static void main(String arguments[]) {
System.out.println("Programme up and running...");
Human myHuman = new Human();
myHuman.scream();
}
Still on the Desktop, I then have another folder which I've named src, inside of which I have created the necessary subfolders corresponding to the package name, i.e. ./src/org/somepackage - and in this location, I have the Human.java file which defines the Human class with the following contents:
package org.somepackage;
public class Human {
public void scream() {
System.out.println("I exist!!");
}
}
I then created a classes folder, again on the Desktop, and ran the following compile command on the command line:
javac -d ./classes/ ./src/org/packagename/Human.java
This ran fine and created - as expected - the Human.class file within the ./classes/org/packagename/ location.
However, where I fall down is when I then try to compile MyProgram.java on the command line, i.e.
javac -cp ".:./classes/" MyProgram.java
As you'll see, my class path contains a reference to the current location (".") for the MyProgram.java file, and it contains a reference to the classes folder ("./classes/") which is the base location for the org.somepackage package inside whose subfolders (./classes/org/somepackage/) on can find the Human.class file.
At this stage, I was simply expecting the java engine to compile MyProgram.java into the program MyProgram.class - but, instead, I get an error:
MyProgram.java:1: error: package org does not exist
I've been following the instructions listed here:
https://www3.ntu.edu.sg/home/ehchua/programming/java/J9c_PackageClasspath.html
and I don't appear to be deviating from the instructions - yet I'm unable to locate an explanation on Stackoverflow or anywhere else as to a possible reason for this compile failure. If anyone has an idea, your help would be very much appreciated.
Thanks,
Your mistake is here
import org.somepackage; <--
public class MyProgram {
public static void main(String arguments[]) {
System.out.println("Programme up and running...");
Human myHuman = new Human();
myHuman.scream();
}
you forgot to import class actually, you need to write this name
import org.somepackage.Human; import all package content import org.somepackage.*; or write full qualified name of class in your code
org.somepackage.Human myHuman = new org.somepackage.Human();
myHuman.scream();
correct mistake:
import org.somepackage.Human;
public class MyProgram {
public static void main(String arguments[]) {
System.out.println("Programme up and running...");
Human myHuman = new Human();
myHuman.scream();
}
after that compile your Human.java by this command:
javac -d classes Human.java
and MyProgram.java
javac -d classes -cp "classes" MyProgram.java
and run MyProgram by
java -cp "classes" MyProgram
I wrote the following piece of code in sublime text on my macbook pro.
I saved the file inside the java folder on my desktop. When I tried to compile the program and tried to execute it, I am getting the fallowing error message " Error: Could not find or load main class Animals ".
Could someone help me in compiling and running this program
package forest;
class Animals{
public static void main(String[] args)
{
Animals s = new Animals();
Sring[] s2 = s.getAllAnimals();
}
public String[] getAllAnimals()
{
String[] s1= {"Lion", "Elephant", "Tiger","Deer","Wolf","Dinosar"};
return s1;
}
}
Make your class Animal as public and rename the file to Animal.java
Your class is in a package called forest so you need to move Animals.java into a directory called forest.
You hava a typo on line 7: Sring[] s2 = should be String[] s2 =.
Compile from the parent directory of forest. Something like this should work
$ javac forest/Animals.java
Run from the parent dir:
$ java forest.Aminals
Your program will have no output when you run it.
Look on your code there is no sring type class in java so change it to String
Sring[] s2 = s.getAllAnimals();
change it to
String[] s2 = s.getAllAnimals();
Everything will be good
try this tutorial Java and the Mac OS X Terminal and Make your class public and also make sure that the file name that contains your source code and the name of your main class is same, your main class is the one that contains main method.
First of all you can name your java file with any name.
Say Sample.java. and let us consider this file is present in D:\work
Go to D:\work folder in cmd prompt.
Keep this in mind :
If you write package forest, then your class has to be public.
So write public class Animals{}
While compiling do this javac -d Sample.java
By doing this the compiler will create the folder "forest" and inside that it will create the Animals.class.
So now in D:\work we have Sample.java file and "forest" folder
Now in your command prompt DO NOT go inside the "forest" folder.
Stay in work folder. D:\work
And Run this command from D:\work java forest.Animals
Explantion::
The name of your class that contains Main method is not Animals. It is forest.Animals This is the fully qualified name of the class. This happened becasue you put a package to it.
So while runnning you must run with fully qualified name
java forest.Animals
The name of your class is not Sample.java. <-- This is just a text file name it anything the complier will not generate a class with name Sample.class because inside this file there is no such class, the class name is Animals. So Animals.class will be generated.
And javac -d Sample.java helps you create the folder structure automatically based on the package.
For example if your class was like this
package com.stackoverflow.samples
public class Animals{
}
And you do java -d Sample.java
The Compiler will create a folder com inside that another folder stackoverflow inside that another folder samples and inside that a file Animals.class
To run this you must run it from outside the the "com" folder with fully qualified name
java com.stackoverflow.samples.Animals
I was trying to execute the following code in java:
import java.awt.*;
import javax.swing.*;
import org.fife.ui.rtextarea.*;
import org.fife.ui.rsyntaxtextarea.*;
public class TextEditorDemo extends JFrame {
private static final long serialVersionUID = 1L;
public TextEditorDemo() {
JPanel cp = new JPanel(new BorderLayout());
RSyntaxTextArea textArea = new RSyntaxTextArea();
textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
RTextScrollPane sp = new RTextScrollPane(textArea);
cp.add(sp);
setContentPane(cp);
setTitle("RSyntaxTextArea 1.4 - Example 1 - Text Editor Demo");
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
}
public static void main(String[] args) {
// Start all Swing applications on the EDT.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TextEditorDemo().setVisible(true);
}
});
}
}
Since I'm using RSyntaxTextArea file i have to give the classpath of it while I'm running the code.
Assume that my RSyntaxTextArea.jar file is in Anto(i.e. my Home directory in Ubuntu 10.10) and when I run the above code:
javac -classpath \Anto\RSyntaxTextArea.jar TextEditorDemo.java
Still I'm getting the error as RTextScrollPane could not be found kind of errors. I guess i have been giving my classpath wrongly; What to do?
Thanks for the answer.
Did you download it from the sourceforge site? It is a zip file containing the sources. Create a folder for containing the sources and unzip it. Run ant in the folder - it will create a rsyntaxtextarea.jar in the dist folder. Add this to the class path.
Assuming that /Anto is really your home directory, try this:
javac -classpath ~/RSyntaxTextArea.jar TextEditorDemo.java
Otherwise, just point to a relative path to the jar file. For one thing, you were trying to use \, where in Linux you should be using /. You can reference the current directory with . So, if the jar is in your current working directory, you can just do this:
javac -classpath RSyntaxTextArea.jar TextEditorDemo.java
Or this:
javac -classpath ./RSyntaxTextArea.jar TextEditorDemo.java
If the Anto directory is under the current directory, use this:
javac -classpath ./Anto/RSyntaxTextArea.jar TextEditorDemo.java
Because that's not the path to your home directory, nor the correct slash to use.
javac -classpath /home/Anto/RSyntaxTextArea.jar TextEditorDemo.java
Also note Java 6 allows you to use a wildcard (*) for the path to search for jar files.