Java class not running on OS X - java

I have a simple program written in Java:
package edu.oakland.lecture;
public class Alfa {
int a;
public int getAttribute() {
System.out.println("returning value of a");
return a;
}
public static void main(String []args) {
Alfa alfa = new Alfa();
int number = alfa.getAttribute();
System.out.println(number);
}
}
It compiles with javac on both windows (xp) and os x (lion), but it only runs on windows.
This is the command I use to compile the program:
javac -d bin source/edu/oakland/lecture/Alfa.java
This is the command I use to execute it:
java -classpath bin; edu.oakland.lecture.Alfa (I also tried -cp instead of -classpath in Terminal)
As I mentioned, I get the expected output on windows side, but I get this message on the os x side:
-bash: edu.oakland.lecture.Alfa: command not found
I know it has to be something stupid simple; what am I overlooking?
Thanks!

The classpath separator on UNIX-like systems (such as OS X) is ':', not ';'. Your command should just be
java -classpath bin edu.oakland.lecture.Alfa
If you actually did have several different components to your classpath, it would look like:
java -classpath bin:foo edu.oakland.lecture.Alfa

Related

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

Enthuware Mock-20 Confusion -classpath and packages

I am using enthuware to practice mock questions for classpath and packages. Here is the question.
//in file ./Foo.java
public class Foo {
public static void main(String[] args) {
System.out.println("In Foo");
}
}
//in file ./com/Foo.java
package com;
public class Foo {
public static void main(String[] args) {
System.out.println("In com.Foo");
}
}
Which of the given statements are correct assuming that the command lines are executed from the current directory with default classpath set to ./classes?
The options given are
Executing java -classpath .:./com Foo will print "In com.Foo"
Executing java -classpath ./com:. Foo will print "In com.Foo"
Executing java Foo will print "In com.Foo"
java -classpath . com.Foo will not execute.
Executing java -classpath ./com:. com.Foo will print "In com.Foo"
Correct option given is option-5. The strange problem is when i try to execute option-5 from my command line it gives me the following error.
Can someone tell me what is wrong? I am not able to figure out the reason. Plus what does this
./com classpath mean?
Command Change
I noticed one strange thing, if i change the classpath and run the command as
java -classpath . com.Foo
It states in com.Foo. As soon as i change the command to add this path ./com. It gives the above mentioned error.
Thanks.
The "./com" is a relative path to the current path.
If you have your class in [current_path]/com/Foo.class
You can run your class with the following command:
java -classpath ./com com.Foo
If you are in the com folder [current_path: com]/Foo.class you can execute the following command:
java -classpath . com.Foo

Can i somehow run previously compiled java bytecode from a new Java program?

Is it possible to first compile a set of Java source code files into bytecode, and later run that bytecode-- not directly, but by adding commands to another java program-- such that this new java program (in its various classes/functions) runs the previously compiled java bytecode?
If this is possible, then what is/are the required command(s) to do this?
Absolutely - and that's what libraries are all about! They're typically distributed as jar files, but you don't have to use jar files in order to reuse the code.
All you need to do is make sure that it's on the classpath at both compile-time and execution time.
For example, create the following files:
lib\p1\Hello.java:
package p1;
public class Hello {
public static void sayHi(String name) {
System.out.println("Hi " + name + "!");
}
}
app\p2\Greeter.java:
package p2;
import p1.Hello;
public class Greeter {
public static void main(String[] args) {
Hello.sayHi(args[0]);
}
}
Now let's compile our "library":
$ cd lib
$ javac -d . p1/Hello.java
$ cd ..
And now, by adding that to the classpath, we can use it in our "app":
$ javac -d . -cp ../lib p2/Greeter.java
$ java -cp .:../lib p2.Greeter Jon
Hi Jon!
(This all works on Windows with the one change of using ";" instead of ":" in the joint classpath on the last line.)

Getting exit value of a shell script 255 every time

I have a jar say test.jar having TestJar as its main class, a shell script jar_executor.sh,and a java file. My test.jar will return 1 if we pass 1 as an argument and 2 if we pass any other value.
My shell script is executing test.jar as follow
#!/usr/bin/ksh
java TestJar 1 -cp test.jar
return_code=$?
exit $return_code
In java file I am creating a process and executing shell script and taking its exitvalue with following code
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(sh jar_executor.sh);
int exitVal = process.waitFor();
System.out.println(exitVal);
This exitVal variable should print 1 or 2 as per argument we are passing but it is printing 255 everytime.
If I use echo $return_code in shell script then I am getting correct value.
Please help me why I am getting value 255 with exit. Thanks in advance!!!
255 or -1 is an application defined exit code, you would have to read the code to know what it means.
A Java application which exits normally, returns 0 and if it throws an Exception, returns 1.
Go to your workspace library, workspace.metadata.plugins\org.eclipse.e4.workbench
and remove the workbench file :) . after that you can restart eclipse
It looks like it might be a Java bug. Others have reported issues similar to what you've seen; see this Java bug report. The Java devs don't think there's a bug but I'm suspicious. The code JRE uses to get the return value from a spawned process is hairy, and I wouldn't be surprised if there's a race condition or other concurrency bug.
I'm guessing that the JRE fails to capture the return code if the spawned process exits very quickly. If my suspicion is correct, adding sleep 1 to your shell script will cause it to work.
Your shell script does not call java correctly:
java TestJar 1 -cp test.jar
You need to set the options for the java command before you mention your main class name. All arguments after your main class name are arguments for your main class and are no longer options for the java VM. So in your case there is no classpath specified for java. I get the following error message when I execute your script: Error: Could not find or load main class TestJar. To fix, you have just to re-order the arguments in your jar_executor.sh script:
java -cp test.jar TestJar 1
I cannot reproduce the 255 on my PC, so I can only guess where that comes from: Either your java command returns an error code of 255 instead of 1 when it fails to load the main class or your korn shell (/usr/bin/ksh) sets this return value when the script is aborted.
Here are all sources I used:
jar_executor.sh
#!/bin/sh -e
java -cp test.jar TestJar 2
return_code=$?
exit $return_code
TestJar.java
public class TestJar {
public static void main(final String[] args) {
System.exit(Integer.parseInt(args[0]));
}
}
JarRunner.java
import java.io.IOException;
public class JarRunner {
public static void main(final String[] args) throws IOException, InterruptedException {
final Runtime runtime = Runtime.getRuntime();
final Process process = runtime.exec("sh jar_executor.sh");
final int exitVal = process.waitFor();
System.out.println(exitVal);
}
}
When I now run java -cp bin JarRunner, I get the output 2 as expected.
You're probably wrong in invoking the script. Try:
Process process = runtime.exec("sh -c jar_executor.sh");
Note the "-c" flag that means you're calling the shell to execute the command.

How do I find my PID in Java or JRuby on Linux?

I need to find the PID of the current running process on a Linux platform (it can be a system dependent solution). Java does not support getting the process ID, and JRuby currently has a bug with the Ruby method, Process.pid.
Is there another way to obtain the PID?
If you have procfs installed, you can find the process id via the /proc/self symlink, which points to a directory whose name is the pid (there are also files here with other pertinent information, including the PID, but the directory is all you need in this case).
Thus, with Java, you can do:
String pid = new File("/proc/self").getCanonicalFile().getName();
In JRuby, you can use the same solution:
pid = java.io.File.new("/proc/self").canonical_file.name
Special thanks to the #stackoverflow channel on free node for helping me solve this! (specifically, Jerub, gregh, and Topdeck)
Only tested in Linux using Sun JVM. Might not work with other JMX implementations.
String pid = ManagementFactory.getRuntimeMXBean().getName().split("#")[0];
You can use the JNI interface to call the POSIX function getpid(). It is quite straight forward. You start with a class for the POSIX functions you need. I call it POSIX.java:
import java.util.*;
class POSIX
{
static { System.loadLibrary ("POSIX"); }
native static int getpid ();
}
Compile it with
$ javac POSIX.java
After that you generate a header file POSIX.h with
$ javah -jni POSIX
The header file contains the C prototype for the function with wraps the getpid function. Now you have to implement the function, which is quite easy. I did it in POSIX.c:
#include "POSIX.h"
#include <sys/types.h>
#include <unistd.h>
JNIEXPORT jint JNICALL Java_POSIX_getpid (JNIEnv *env, jclass cls)
{
return getpid ();
}
Now you can compile it using gcc:
$ gcc -Wall -I/usr/lib/jvm/java-1.6.0-sun-1.6.0.21/include -I/usr/lib/jvm/java-1.6.0-sun-1.6.0.21/include/linux -o libPOSIX.so -shared -Wl,-soname,libPOSIX.so POSIX.c -static -lc
You have to specify the location where your Java is installed. That's all. Now you can use it. Create a simple getpid program:
public class getpid
{
public static void main (String argv[])
{
System.out.println (POSIX.getpid ());
}
}
Compile it with javac getpid.java and run it:
$ java getpid &
[1] 21983
$ 21983
The first pid is written by the shell and the second is written by the Java program after shell prompt has returned. ∎
Spawn a shell process that will read its parent's pid. That must be our pid. Here is the running code, without exception and error handling.
import java.io.*;
import java.util.Scanner;
public class Pid2
{
public static void main(String sArgs[])
throws java.io.IOException, InterruptedException
{
Process p = Runtime.getRuntime().exec(
new String[] { "sh", "-c", "ps h -o ppid $$" });
p.waitFor();
Scanner sc = new Scanner(p.getInputStream());
System.out.println("My pid: " + sc.nextInt());
Thread.sleep(5000);
}
}
This solution seems to be the best if the PID is to be obtained only to issue another shell command. It's enough to wrap the command in back quotes to pass it as an argument to another command, for example:
nice `ps h -o ppid $$`
This may substitue the last string in the array given to exec call.
Java 9 finally offers an official way to do so with ProcessHandle:
ProcessHandle.current().pid();
This:
First gets a ProcessHandle reference for the current process.
In order to access its pid.
No import necessary as ProcessHandle is part of java.lang.
You can try getpid() in JNR-Posix.
It also has a Windows POSIX wrapper that calls getpid() off of libc. No JNI needed.

Categories