How to change the classpath and run the code in Java? - java

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.

Related

How to correctly create and import packages in Java

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");
}
}

Execution Java -cp

I have a doubt about -cp and when should I use it. This is my scenario:
I have two .java, the first one:
package autos.tests.paquete;
public class MainAutos {
public static void main(String args[]) {
int x = Integer.parseInt(args[0]);
Respotar objeto1 = new Respotar (x);
int mostrar = objeto1.repostar();
System.out.println(mostrar);
}
}
And the second one:
package autos.tests.paquete;
public class Respotar {
int gasolina;
public Respotar (int gasolina) {
this.gasolina=gasolina;
}
public int repostar (){
int gasolina = this.gasolina +20;
return gasolina;
}
}
Well, I am at root directory, and there, I have that directory: autos/tests/paquete
with both .java.
So I compile:
javac autos/tests/paquete/*.java
And execute from root directory:
java autos.tests.paquete.MainAutos 10
And it works, now here go my doubts:
1) I execute with java -cp . autos.tests.paquete.Main autos 10 and the behaviour is the same.
2) I move the Respotar.class from auto/tests/paquete to another directory, I compile with
java autos.tests.paquete.MainAutos 10 and it works.
3) I move the MainAutos.class from auto/tests/paquete to another directory, I compile with
java autos.tests.paquete.MainAutos 10 and it says: Error: Could not find or load main class autos.tests.paquete.MainAutos
4) I compile with java -cp . autos.tests.paquete.MainAutos (I have the .class on the current directory I am compiling, so I think I have to use -cp .) and it says the same:
Error: Could not find or load main class autos.tests.paquete.MainAutos
Thank you in advance, I hope someone can enlighten me, regards
java -cp is used to set any libraries such as jar file to your current classpath.
For the examples you have shown, you can do it in the below simple way
From you root directory compile your java files using the below command
javac -d . *.java
This would created those appropriate packages and place the class files under them
Then run you code using the command like this from the same root location
java autos.tests.paquete.MainAutos

Java isn't automatically including class

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

can't get the classpath right

i'm trying to compile this slick2d example (first one) but i can't get it to work. here's the code:
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
/**
* #author panos
*/
public class WizardGame extends BasicGame
{
public WizardGame()
{
super("Wizard game");
}
public static void main(String[] arguments)
{
try
{
AppGameContainer app = new AppGameContainer(new WizardGame());
app.setDisplayMode(500, 400, false);
app.start();
}
catch (SlickException e)
{
e.printStackTrace();
}
}
#Override
public void init(GameContainer container) throws SlickException
{
}
#Override
public void update(GameContainer container, int delta) throws SlickException
{
}
public void render(GameContainer container, Graphics g) throws SlickException
{
}
}
i've put lwjgl.jar, slick.jar and ibxm.jar in the directory as instructed. then i tried:
javac -classpath .;full path\slick.jar.;full path\lwjgl.jar;full path\ibxm.jar
then
java WizardGame
but i get errors that the jar classes aren't defined, which means something must be wrong when i'm setting the classpaths. i'm not sure what i'm doing wrong though.
i've also tried
javac -classpath .;.\slick.jar.;.\lwjgl.jar;.\ibxm.jar
either way, shouldn't the jvm find out about the .jar files on its own if they're on the same directory as the source code? in my case, i've set up the 3 jars in the same directory as WizardGame.java. if i try compiling without the -classpath arguments it doesn't work though.
edit:
i did as instructed, but now it's telling me "no lwjgl in java.library.path"
i examined my lwjgl.jar with winrar and saw that it contains two folders: meta-inf and org, and then inside org there is lwjgl. is it supposed to be like that? because if it is, i dunno what's wrong.
edit 2:
created the manifest with what you said, then used:
jar cfm test.jar manifest.txt
this created a jar file, then i used
java -jar test.jar
and then it told me it didn't find the definition for the class WizardGame.
You have to add the -classpath option to the java command also. Not only to the compiler.
like:
javac -classpath .;lib\myjar.jar MyClass.java
and then
java -classpath .;lib\myjar.jar MyClass
Otherwise the interpreter ( java ) won't know where to find the classes needed.
Oscar is bang on - you need the -classpath on the java command too.
Another thing you can look at (it is overkill for what you are doing now, but you should still do it for the experience) is to create a JAR file. In the JAR file you can provide a manifest.mf file that tells the java command where to find the other JAR files as well as what the main class is.
You would then run your program via "java -jar foo.jar"
http://java.sun.com/docs/books/tutorial/deployment/jar/manifestindex.html
http://java.sun.com/docs/books/tutorial/deployment/jar/appman.html
http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html
I believe that the following manifest.m file will do what you want (note you have to have a blank line at the end or it will not work):
Main-Class: WizardGame
Class-Path: slick.jar lwjgl.jar ibxm.jar
That assumes that all JAR files (foo.jar and the other three) are in the same directory.

How do relative file paths work in Eclipse?

So my 2009 new years resolution is to learn Java. I recently acquired "Java for Dummies" and have been following along with the demo code in the book by re-writing it using Eclipse. Anyway, every example in the book that uses a relative path does not seem to read the .txt file it's supposed to read from.
Here is the sample code:
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.GridLayout;
class TeamFrame extends JFrame {
public TeamFrame() throws IOException {
PlayerPlus player;
Scanner myScanner = new Scanner(new File("Hankees.txt"));
for (int num = 1; num <= 9; num++) {
player = new PlayerPlus(myScanner.nextLine(), myScanner.nextDouble());
myScanner.nextLine();
addPlayerInfo(player);
}
add(new JLabel());
add(new JLabel(" ------"));
add(new JLabel("Team Batting Aberage:"));
add(new JLabel(PlayerPlus.findTeamAverageString()));
setTitle("The Hankees");
setLayout(new GridLayout(11,2));
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
void addPlayerInfo(PlayerPlus player) {
add(new JLabel(player.getName()));
add(new JLabel(player.getAverageString()));
}
}
And you can see in the below screen shot I have included this file.
image no longer available
Also, I have verified that when I build the application that a copy of Hankees.txt is placed in the bin folder with the compiled .class files.
Lastly, if I change line 12 to the following and place Hankees.txt in the root of my C:\ drive the program compiles and runs fine.
Scanner myScanner = new Scanner(new File("C:\\Hankees.txt"));
So basically, my question is what am I doing wrong? Or is Eclipse responsible for this in some way?
Thanks for any and all help!
You need "src/Hankees.txt"
Your file is in the source folder which is not counted as the working directory.\
Or you can move the file up to the root directory of your project and just use "Hankees.txt"
A project's build path defines which resources from your source folders are copied to your output folders. Usually this is set to Include all files.
New run configurations default to using the project directory for the working directory, though this can also be changed.
This code shows the difference between the working directory, and the location of where the class was loaded from:
public class TellMeMyWorkingDirectory {
public static void main(String[] args) {
System.out.println(new java.io.File("").getAbsolutePath());
System.out.println(TellMeMyWorkingDirectory.class.getClassLoader().getResource("").getPath());
}
}
The output is likely to be something like:
C:\your\project\directory
/C:/your/project/directory/bin/
This is really similar to another question.
How should I load files into my Java application?
How should I load my files into my Java Application?
You do not want to load your files in by:
C:\your\project\file.txt
this is bad!
You should use getResourceAsStream.
InputStream inputStream = YourClass.class.getResourceAsStream(“file.txt”);
And also you should use File.separator; which is the system-dependent name-separator character, represented as a string for convenience.
Yeah, eclipse sees the top directory as the working/root directory, for the purposes of paths.
...just thought I'd add some extra info. I'm new here! I'd like to help.
You can always get your runtime path by using:
String path = new File(".").getCanonicalPath();
This provides valuable information about where to put files and resources.
Paraphrasing from http://java.sun.com/javase/6/docs/api/java/io/File.html:
The classes under java.io resolve relative pathnames against the current user directory, which is typically the directory in which the virtual machine was started.
Eclipse sets the working directory to the top-level project folder.

Categories