Call java file using relative path in bash shell - java

bash
/Desktop/Lab 3$ cd Stemmer
/Desktop/Lab 3/Stemmer$ java Stemmer
/Desktop/Lab 3/Stemmer$ cd ..
/Desktop/Lab 3$ java Stemmer/Stemmer
Error: Could not find or load main class Stemmer.Stemmer
Caused by: java.lang.NoClassDefFoundError: Stemmer (wrong name: Stemmer/Stemmer)
/Desktop/Lab 3$
Why doesn't java run Stemmer when I specify a relative path?
It seems to have run the program when I was in the directory, but I want java to run Stemmer as it did when I was in the directory that it was located in.
Could someone explain what is happening here please.

When you run a Java program, you specify the class name including the fully specified package, not the file path. This means that you separate the package "path" with dots, not slash. If you compiled a file named Stemmer.java that is in a folder named Stemmer and has package Stemmer as the first line, then you do
java Stemmer.Stemmer

There are 2 broad options:
You are trying to write an application in java
Then you need an IDE to develop it in, and a build system to produce the distributables, in the form of a jar file. There is no point or reason to trying to run this 'on the command line' the way you are. You need packages and a project definition.
You are just toying around for now, writing some basic code in a single source file.
Then just run the source file. This is a feature introduced in, I think, java11. Before that, this model of writing (stuff some lines in a source file and run it right away) is not what java itself is good at, only IDEs do that properly.
Starting with java11:
java Stemmer/Stemmer.java
works great, and no need to (re)compile anything. java will take care of it.
Explanation
When you run a Java program, you specify the class name including the fully specified package, not the file path.
You read this answer before, and then proceeded to completely ignore it and try java Stemmer.Stemmer which obviously doesn't work.
The class you have is named Stemmer, and it is in the unnamed package. Thus, to run it, java Stemmer is how to do this. It's not a file name. Stemmer.Stemmer is not java-ese for 'run the class file Stemmer in the subdirectory Stemmer, and 'package' is not java-ese for 'directory on the filesystem'.
The classpath root for your Stemmer class is its own directory, as you are not using any packages. the default classpath is the current directory. It is not possible to run the Stemmer class file without having its root on the classpath, so if /Desktop/Lab 3/Stemmer is not on the cp, you can't do it. So let's fix this:
java -cp '/Desktop/Lab 3/Stemmer' Stemmer
and that'll work fine.
More generally, using the unnamed package is a bad idea, and trying to run raw class files is similarly a bad idea - use an IDE for development, and a build system to build projects.
These rules and caveats all make perfect sense when writing a 'real' project (one you check into source control, and eventually deploy someplace or ship as a product to other users). But it's onerous and a tad ridiculous if just messing around. That's exactly why (these days) you can just specify a path to a java source file, which seems to be what you want to do. So, do that.

Related

Is there a clean way to fix files path issue whether the program is launched from console or Eclipse?

I'm currently working on a Java project in which I have to open files I stored in a data directory next to src.
When I launch my program from Eclipse, to access these files: I type "data/fileName" whereas when I use console I have to type "../data/fileName".
(I couldn't manage to execute java src/Main from project directory and got the error :
Error: Could not find or load main class src.Main.java
Caused by: java.lang.ClassNotFoundException: src.Main.java )
Is there a way to make my program runnable on both console and Eclipse?
To give some context: I usually intended to run only on Eclipse but I encountered issues launching nano from Eclipse ($TERM variable , redirecting pipes to dev/tty also) so console execution has become a requirement.
I can't change my Eclipse configuration since this project won't be run on my computer and if it doesn't run because of default Eclipse settings, well...
Thank you for your replies.
Cordially.
Yes. Don't put those files there. There are 2 broad categories:
Read-only data that is as much a part of your app as your class files are. Think 'list of US states for the 'state' dropdown', 'an icon png to be shown on my user interface', 'a file containing a bunch of SQL to be used to initialize an empty database', and more.
For this, the proper way to go is YourClass.class.getResourceAsStream("foo.txt"), which will give you an input stream for reading the file "foo.txt", which is in the same place "YourClass.class" is. Even if it is in a jar file, for example.
This does mean that as part of your build, these files need to be in the jar. eclipse's limited build system does this. If you level up as a programmer and use a build system (you should be levelling up here), put them in src/main/resources and the build system should take care of it.
Or, the second category: Files that the user is supposed to edit, or files that need to be modified by your app.
These don't go anywhere near your jar file; executable and user-editable stuff should be nowhere near each other. These should be in the user home dir, you can fetch it with System.getProperty("user.home").
Note that to run java stuff, 'src' shouldn't be part of the story at all, java can't run source files, only class files. Also, the argument isn't a dir, it's a class name. java -cp path/to/your/app.jar com.foo.pkg.YourClass is how you run java code, not java src/Main.

Exporting a runnable jar, opening it returns an UnsatisfiedLinkError

I currently wrote a simple GUI in Eclipse which runs as intended. I was hoping to export it so I can share it with my friend (who doesn't need to install eclipse and the java libraries). I tried all 3 library handling method Eclipse provides and none of them works. I read a little online and saw something about a manifest file, but wasn't quite sure what to do with it. Is it going to help?
This is where I placed the folder that comes with the .dll file.
This is the result. Am I doing something wrong?
As indicated by the error messages in the first screenshot, what you are missing here is the native library - the software library written and compiled to native code specific to the operating system. What you will need to do is provide the libraries specific to the operating system on which your software will run, eg. dlls for 32 or 64 bit Windows. The manifest does not provide the capability to include those libraries.
When the program is run on Windows, Java will look for native libraries in the following locations:
The current directory
The directories in the PATH environment variable
The directories in java.library.path (if it's specified)
It may be easiest to simply put all files in the one directory. If you do this, you should be able to run the program in the same way as you do now.
The java.library.path option is only needed if you want to put your native library files in a directory separate to the one in which you run your program and not on your PATH. It is only in this case that you will need to add java.library.path, eg. by adding -Djava.library.path=c:\path\to\your\lib after java. Also note that you may use a relative path, ie. a path that is relative to the directory you are in when you execute the command.
I also see from your later error messages that you have another dependency, but on a java library LeapJava.jar. As running a jar with -jar will only work if you have a single jar, but because you have more than one (your own program plus the dependency), you'll instead need to use the -classpath (or -cp for short) argument and add your main class. The classpath argument is a semicolon-separated list of classpath locations, while the main class is the one containing your public static void main method, eg. your.package.name.YourMainClass. So assuming your UI.jar is still in C:\Users\Ian\Desktop\Leap Data UI, you should be able to navigate to that directory and execute with:
java -cp UI.jar;UI_lib\LeapJava.jar -Djava.library.path="UI_lib\x64" your.package.name.YourMainClass

What are Java Classpath and Path?

I have been googling around, trying to understand what the Java Classpath and Path are. However, I am stil not quite sure if I have understood it or not. If feel that this topic is one of those grey areas.
Can someone explain me what those are? I mean, where do I find and set them (where is the actual text file on Mac/Windows)? Is there only one instance of each one? If so, how do I set the path for multiple classes?
As you might have notices, I am totally confused right now after reading so many different tutorials... So now I really would like to have a straight forward explanation.
Please help me, I just trying to learn :)
Thank you all
A path is just a folder location. The path is where your OS will look for programs by default. If java, javac, javap, etc, etc, are in your path then you can just type their names without the entire folder location.
Your classpath is similar. It is a set of folders that contain .class files describing classes(hence the name) and .jar files, which are basically files that contain .class files. All code that you're running is either out of the classpath, generated, or out of the java libaries(also part of the classpath, techncically).
With each run of a java program you can specify a classpath by parameters passed to the java executable. It also grabs classes out of "extension folders,", special folders Java keeps around to act as a system classpath, and finally, the "bootstrap classes", which are a set of important classes almost any Java program needs to run.
Simple mean of path is location of file system. if you want to access any file then you have to manually needs to go there location.
just example: d:\text1.txt then needs to go that d:\ location. same way java program have command like
javac -for compile
java - for run
.
.
.
etc.
that inside java-jdk\bin folder
so if you don't set into classpath. then you can execute java program like
run->cmd
c:\jdk1.6\bin> javac test.java
so without going explicit way you can set it into classpath, and direct execute java program from anywhere.
You can set java path as environment variable of computer.
The PATH is basically where your JDK is installed; this is essentially what your IDE will look for when trying to compile or create Javadoc or such; it's basically just the location of a folder on your hard drive, set as a Windows (or other OS) environment variable to make it easier to use.
The CLASSPATH is a property that tells the compiler where to look for classes. Basically if you download a library or such from somewhere, you need to add it to the CLASSPATH for the compiler to use it. Usually you can do this in your IDE, however, you should not need to directly access the CLASSPATH variable.
By the way, the Wikipedia article is pretty helpful.
1)java Path: it is location of binary executable files
example :javac , java
this file are used for compile and run
2)class Path: it is location of .class file(file create after compile your source code .java file)

Don't packages have to match the subdirectories the java file is in?

I was writing some practice programs for my java certification this morning, and noticed that I had mistyped a package name, so it didn't match the subdirectory the java file was in. I compiled the code expecting an error, but everything compiled file -- not even a warning.
I googled around a bit, and most of the pages I read said that the package name had to match the subdirectory. My experience shows that's not the case.
When I attempted to run the program, it didn't work because the .class file was in the wrong directory. I moved it to the correct directory, and got this error:
Exception in thread "main" java.lang.NoClassDefFoundError: com/sample/directory
/doesnt/even/exist/OtherPackageMemberModifiers (wrong name: com/sample/chap01/O
therPackageMemberModifiers)
So what I think I'm seeing is that Java code will compile if the package and the subdirectory don't match up, but there doesn't seem to be a way to run the code if you do that. Is that correct?
The package name has to match the directory name in order for the class file to be found correctly. It doesn't have to match the directory name at compilation time for some compilers (e.g. javac) although others (such as Eclipse) will at least give a warning.
The "way to run the code if you do that" is to create the directory structure and put it in there manually - the class file itself is entirely valid.
Note that if you use the -d flag, javac will build the appropriate directory hierarchy for you, regardless of source location. For example:
javac -d bin ClassInPackage.java
will create any required directories under bin to match the package declared in ClassInPackage.java.
Having said all of thise, I'd still strongly encourage you to make the source directories match the packages, even though you can get away without it :)

Compiling Java package throws errors for external Jars

Pretty basic problem here. So I have a Java package that I have created that has three classes (one has the main method). I am trying to use a few Apache Jars, and have added these to my build path in Eclipse. However Eclipse wont let me build and run it properly, so I am trying the command line. I have added the env var CLASSPATH and pointed it to my lib directory which hold the Apache Jars. However, when I try to use javac I get a bunch of errors:
package org.apache.xmlrpc does not exist
import org.apache.xmlrpc.client.XmlRpcClient;
I was reading the man page for javac and it said that:
If neither CLASSPATH, -cp nor -classpath is specified, the user class path consists of the current directory.
So I tried copying the Jars to the same location as my three source files, but no change.
Can someone please tell me what I'm doing wrong?
Thanks.
Classpath variable (or command line option of javac) must contain all jars explicitly. It cannot go through jar files stored in specified directory.
You can compile this by specifying the option -cp on the command line:
javac -cp foo.jar:bar.jar foo/bar/Baz.java
You then run it with the same option:
java -cp foo.jar:bar.jar foo.bar.Baz
It sounds like you've just set the classpath to the directory containing the jar files. You need to set it to the individual jar files, or use java.ext.dirs to set an "extension" directory containing jar files. I'd recommend using the specific jar files. Something like:
// Assuming Windows...
CLASSPATH = c:\libs\foo.jar;c:\libs\bar.jar
I'd also personally recommend specifying the classpath on the command line instead of using an environment variable - the latter will work, but it ends up being a bit more fiddly if you want to compile different projects against different libraries.
However, I'd actually recommend getting Eclipse working first, rather than retreating to the command line. It should be fine - if you could give us more information about what's failing in Eclipse, we may be able to help you with that instead.
The jar files in the current directory are not automatically included; that only refers to .class files in normal package/directory hierarchy. Jar files must be added either explicitly, or via a wildcard like javac -cp ./* (Assuming JDK6+)
(Some OSes may require an escape of the * to avoid globbing; OSX does not.)
I agree with previous answers, but I would also recommend to use proper java build tool - like ant (perceived easier to use, but not necessary) or maven ( perceived more difficult to use, but really worth learning )

Categories