ProcessBuilder call another java file same package - java

I am learning how to use ProcessBuilder, I created a package called socketspractice, inside I have 2 classes, I am trying to create a new process where 'Program.java' calls 'test1.java' so it prints 'test1'.
When I use command prompt: "java socketspractice.test1" 'test1' prints, but using Netbeans it doesn't.
The question is, how can I set the path so it works the same way or what else am I missing? I am using Netbeans for this.
Program.java
package socketspractice;
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder;
public class Program {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder builderExecute = new ProcessBuilder("java", "socketspractice.test1");
builderExecute.start();
}
}
AND
test1.java
package socketspractice;
public class test1 {
public static void main(String[] args) {
// TODO code application logic here
System.out.println("test1");
}
}

The main issue with ur approach is that when you are starting ProcessBuilder it doesnt know where ur project lies on your machine, because its running as a seperate JVM process.
So please create you project as a maven project and then try to put the compiled jar in classpath and then start the process builder.
ProcessBuilder pb = new ProcessBuilder("java","-classpath",
"<complete location of your jar containing test1>", "socketspractice.test1")

Related

Cannot see print and println statements in Eclipse using JEP/Pydev

I'm learning JEP and PyDev plugin eclipse and new to Python.
I cannot see my python print and java println statements on Eclipse console tab.
As I'm just trying things out I create a simple python script by creating a new PyDev module and it just has one line (greetings.py):
print("Hello from python");
When I run this I see it in the console when I run it both the PyDev and Jave EE perspective.
Next as the intent of this exercise is to look into JEP to see if it's adequate for my project so I created another Java project with this code:
package my.sand.box;
import jep.Interpreter;
import jep.Jep;
import jep.JepException;
import jep.SharedInterpreter;
public class JepTest {
public static void main(String[] args) throws JepException {
// TODO Auto-generated method stub
System.out.println("hey");
try (Interpreter interp = new SharedInterpreter()) {
//interp.exec("import example_package");
// any of the following work, these are just pseudo-examples
interp.runScript("full/path/to/greetings.py");
interp.eval("import sys");
interp.eval("s = 'Hello World'");
interp.eval("print s");
String java_string = interp.getValue("s").toString();
System.out.println("Java String:" + java_string);
}
}
}
I don't see anyting on the console. Not even the java println statements.
I also recreated both projects in a new workspace and could see the output. What's different between both workspaces is that in the one that's not workign I have other java projects and pydev projects open.
Would appreciate any advice.
I've faced a similar issue working with Jep before, the trick is you need to redirect Python's output stream in your IDE by calling the correct method.
Take a look at https://github.com/ninia/jep/issues/298
As Klodovsky mentioned, you need to redirect Python's output to the stream used by the IDE. I've adapted your example to do this. The key line is the call to SharedInterpreter.setConfig:
package my.sand.box;
import jep.Interpreter;
import jep.JepConfig;
import jep.JepException;
import jep.SharedInterpreter;
public class JepTest {
public static void main(String[] args) throws JepException {
System.out.println("hey");
// Eclipse doesn't use stdout & stderr, so use the streams from Java.
SharedInterpreter.setConfig(new JepConfig()
.redirectStdErr(System.err)
.redirectStdout(System.out));
try (Interpreter interp = new SharedInterpreter()) {
// interp.exec("import example_package");
// any of the following work, these are just pseudo-examples
// Uncomment if you've created a greetings.py script.
// interp.runScript("full/path/to/greetings.py");
interp.eval("import sys");
interp.eval("s = 'Hello World'");
interp.eval("print(s)");
String java_string = interp.getValue("s").toString();
System.out.println("Java String:" + java_string);
}
}
}

Running Cucumber project using Main.run from another main method

I am new to Cucumber and trying to solve simple issue:
I have created a Java Project and referred all the cucumber related jars to the build-path of this project (called it "CukeTest4") and below is the structure showing the java file and feature file. When I run this feature file as Cucumber feature in Eclipse, it runs fine.
Now, I would like to run this from another main method. I created another Java Project, Added a Class with main method with code below which is in default package.
import cucumber.api.cli.Main;
public class UseCukeFromMain {
public static void main(String[] args) throws Throwable
{
Main.main(new String[]{"-g", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke/cukefeature.feature"});
}
}
I have provided implementation for the method in the java file as it works fine from Eclipse but shows the message below to implement the method
[33mU[0m
1 Scenarios ([33m1 undefined[0m)
1 Steps ([33m1 undefined[0m)
0m0.000s
You can implement missing steps with the snippets below:
#Given("^I want to write a step with precondition$")
public void i_want_to_write_a_step_with_precondition() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
I have tried a lot of combination for -g option, but the message is same.
EDIT2
From the comments below, adding the package to glue when the other project is in classpath, works fine.
Main.main(new String[]{"-g", "com.cuke", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke/cukefeature.feature"};
But, Another issue:
I have some old projects that I need to integrate with cucumber. All the .class and .java are present in the folder(NO src or bin directory):
C:\work\RFT_WS2\Cuketest3
, I have this directory in the Classpath. I have tried following option but unable to understand the issue:
-g "" path/to/feature //(NOT WORKING)
-g "classpath:" path/to/feature //(NOT WORKING)
-g "Cuketest3" // Added "C:\work\RFT_WS2" in classpath (NOT WORKING)
Now if I add the .java file to a package say "steps" and have "C:\work\RFT_WS2\Cuketest3" in classpath, option looks like
-g "steps" path/to/feature //(WORKING)
My question is that how to get it to find the methods implementation for a default package.
Also how do add multiple glue option, for example
Not Working cases I tried
Main.main(new String[]{"-g", "com.cuke,com.cuke1", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke/cukefeature.feature"};
Main.main(new String[]{"-g", "com.cuke", "com.cuke1", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke/cukefeature.feature"};
Thanks.
The glue option takes a path value which reflects the package(s) of the glue classes to be included in the classpath.
Find a simplified working example below
Assume following structure
/tmp/cuke-test/features/cukefeature.feature
/tmp/cuke-test/lib
/tmp/cuke-test/project1/src/com/cuke/CukeSteps.java
/tmp/cuke-test/project2/src/UseCukeFromMain.java
cukefeature.feature
Feature: simple test
Scenario: test programatic call of Cucumber
Given we have feature file
When some glue code exists
Then those steps should not fail
lib
cucumber-core-2.1.0.jar
cucumber-html-0.2.6.jar
cucumber-java-2.1.0.jar
cucumber-jvm-deps-1.0.6.jar
cucumber-testng-2.1.0.jar
gherkin-5.0.0.jar
jcommander-1.64.jar
snakeyaml-1.17.jar
tag-expressions-1.0.1.jar
testng-6.11.jar
CukeSteps.java
package com.cuke;
import cucumber.api.PendingException;
import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.en.*;
public class CukeSteps {
#Given("^we have feature file$")
public void we_have_feature_file() throws Throwable {
System.out.println("execute Given step");
}
#When("^some glue code exists$")
public void some_glue_code_exists() throws Throwable {
System.out.println("execute Then step");
}
#Then("^those steps should not fail$")
public void those_steps_should_not_fail() throws Throwable {
throw new PendingException();
}
}
UseCukeFromMain.java
import cucumber.api.cli.Main;
public class UseCukeFromMain {
public static void main(String[] args) throws Throwable {
Main.main(new String[]{
"--glue",
"com/cuke", // the package which contains the glue classes
"/tmp/cuke-test/features/cukefeature.feature"}
);
}
}
compile the classes
javac -cp "lib/*" -d project1/bin/ project1/src/com/cuke/*.java
javac -cp "lib/*" -d project2/bin/ project2/src/*.java
run the UseCukeFromMain
The root direcotry which contains the glue classes (project1/bin) must be in the classpath.
java -cp "project2/bin:project1/bin:lib/*" UseCukeFromMain
output
execute Given step
execute Then step
1 Scenarios (1 pending)
3 Steps (1 pending, 2 passed)
0m0.104s
cucumber.api.PendingException: TODO: implement me
at com.cuke.CukeSteps.those_steps_should_not_fail(CukeSteps.java:21)
at ✽.those steps should not fail(/tmp/cuke-test/features/cukefeature.feature:6)
edit Using Step definitions in default package
Assume following structure
features/cukefeature.feature
lib/
project1/src/CukeSteps.java
project2/src/UseCukeFromMain.java
cukefeature.feature
lib/
the same as in the first example
CukeSteps.java
// note: there is no package statement
import cucumber.api.PendingException;
import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.en.*;
public class CukeSteps {
#Given("^we have feature file$")
public void we_have_feature_file() throws Throwable {
System.out.println("execute Given step");
}
#When("^some glue code exists$")
public void some_glue_code_exists() throws Throwable {
System.out.println("execute Then step");
}
#Then("^those steps should not fail$")
public void those_steps_should_not_fail() throws Throwable {
throw new PendingException();
}
}
UseCukeFromMain.java
import cucumber.api.cli.Main;
public class UseCukeFromMain {
public static void main(String[] args) throws Throwable {
Main.main(new String[]{
"--glue",
"", // to used Step definitions in default package
"features/cukefeature.feature"}
);
}
}
compile classes
The option -d . creates the class files in the current directory.
javac -cp "lib/*" -d . project1/src/*.java
javac -cp "lib/*" -d project2/bin/ project2/src/*.java
created class files
CukeSteps.class
project2/bin/UseCukeFromMain.class
run the UseCukeFromMain
The current directory is added to the classpath using the ..
java -cp "project2/bin:.:lib/*" UseCukeFromMain
output
execute Given step - default package
execute Then step - default package
1 Scenarios (1 pending)
3 Steps (1 pending, 2 passed)
0m0.096s
cucumber.api.PendingException: TODO: implement me
at CukeSteps.those_steps_should_not_fail(CukeSteps.java:19)
at ✽.those steps should not fail(features/cukefeature.feature:5)
edit Using Step definitions from different packages.
Assume following structure
features/cukefeature.feature
lib
project1/src/com/cuke1/CukeStepsB.java
project1/src/com/cuke/CukeStepsA.java
project2/src/UseCukeFromMain.java
cukefeature.feature
lib/
the same as in the first example
The Step definitions are split in two classes, in different packages
CukeStepsA.java
package com.cuke;
import cucumber.api.PendingException;
import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.en.*;
public class CukeStepsA {
#Given("^we have feature file$")
public void we_have_feature_file() throws Throwable {
System.out.println("execute Given step - package com.cuke");
}
}
CukeStepsB.java
package com.cuke1;
import cucumber.api.PendingException;
import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.en.*;
public class CukeStepsB {
#When("^some glue code exists$")
public void some_glue_code_exists() throws Throwable {
System.out.println("execute Then step - package com.cuke1");
}
#Then("^those steps should not fail$")
public void those_steps_should_not_fail() throws Throwable {
throw new PendingException();
}
}
UseCukeFromMain.java
import cucumber.api.cli.Main;
public class UseCukeFromMain {
public static void main(String[] args) throws Throwable {
Main.main(new String[]{
"--glue",
"com/cuke",
"--glue",
"com/cuke1",
"features/cukefeature.feature"}
);
}
}
compile classes
javac -cp "lib/*" -d project1/bin/ project1/src/com/cuke/*.java project1/src/com/cuke1/*.java
javac -cp "lib/*" -d project2/bin/ project2/src/*.java
created class files
project1/bin/com/cuke1/CukeStepsB.class
project1/bin/com/cuke/CukeStepsA.class
project2/bin/UseCukeFromMain.class
run the UseCukeFromMain
java -cp "project2/bin:project1/bin:lib/*" UseCukeFromMain
output
execute Given step - package com.cuke
execute Then step - package com.cuke1
1 Scenarios (1 pending)
3 Steps (1 pending, 2 passed)
0m0.114s
cucumber.api.PendingException: TODO: implement me
at com.cuke1.CukeStepsB.those_steps_should_not_fail(CukeStepsB.java:16)
at ✽.those steps should not fail(features/cukefeature.feature:5)
The absolute path is required for feature file. The step def directory requires classpath format.
public static void main(String[] args) throws Throwable {
//Your code to get feature file full path
Main.main(new String[]{"-g", "classpath to step definition file", "Full path to feature file"});
}

Open any file from within a java program

Opening files in java seems a bit tricky -- for .txt files one must use a File object in conjunction with a Scanner or BufferedReader object -- for image IO, one must use an ImageIcon class -- and if one is to literally open a .txt document (akin to double-clicking the application) from java, this code seems to work:
import java.io.*;
public class LiterallyOpenFile {
public static void main(String[] args) throws IOException {
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("notepad Text.txt");
}
}
I'm not positive, but I think other file-types / names can be substituted in the parenthesis after exec -- anyway, I plan on opening certain files in a JFileChooser when the user clicks on a file to open (when the user clicks on a file, the path to the file can be obtained with the getSelectedFile() method). Though I'm more specifically looking to be able to open an Arduino file in the Arduino IDE from a java program, like a simulated double-click.. perhaps something like this?
import java.io.*;
public class LiterallyOpenFile {
public static void main(String[] args) throws IOException {
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("Arduino C:\\Arduino\\fibonacci_light\\fibonacci_light.ino");
}
}
A point in the right direction would be appreciated.
Have you tried this? If there is a registered program for your file in windows, this should work. (i.e. the default application should open the file)
Desktop desktop = Desktop.getDesktop();
desktop.open(file);
The file parameter is a File object.
Link to API
Link to use cases and implementation example of the Desktop class
This is what I do in my projects using java.awt.Desktop
import java.awt.Desktop;
import java.io.IOException;
import java.io.File;
public class Main
{
public static void main(String[] args) {
try {
Desktop.getDesktop().open(new File("C:\\Users\\Hamza\\Desktop\\image.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
}

Jar Maker -- Which is the main class?

Alrighty, so I'm working on making a .jar for a client for a little game and I know how to use everything and have done this before, on windows, now i'm on a mac. This shouldn't make a difference but incase you wanted to know, there you go.
Now, I have a folder in eclipse named client, now normally the client.java is the main class but there is another named EGUI, this has the "public static void main(String[] args)", but in my client.java file, it also has a method like this:
public static final void main(String args[])
{
try
{
anInt957 = 0;
anInt958 = 0;
method52(false);//highmem
aBoolean959 = true;//members
signlink.storeid = 32;
signlink.startpriv(InetAddress.getLocalHost());
client client1 = new client();
client1.method1(503, false, 765);
setserver(args[0], "5555");
return;
}
catch(Exception exception)
{
return;
}
}
I guess my question is, does the "final" make it the main file? Or would it still be the EGUI, which looks like this:
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class EGUI
{
public static void main(String args[])
{
client.main(new String[] {
"127.0.0.1", "127.0.0.1", "127.0.0.1"
});
}
}
So, what i'm asking for is, why is it that when I'm setting the main file to EGUI, it isnt working? the applet opens up, but I keep getting an "error connecting to server" message every time, when I run it through terminal by copying the run.bat info and pasting that, it works perfectly! Any help is greatly appreciated!
public static void main(String args[]) means you can execute the class from the commandline. The final keyword means the method cannot be overridden by a sub class.
In your case this does not make it the jar's main execution class. The main class is set in META-INF/MANIFEST.MF. Normally it should have a line:
Main-Class: classname
but then with the actual class.
So open the jar with a zip program, and check MANIFEST.MF.
Your client.java has a main method, for testing purposes I suppose.

How to run a jar file from a separate jar file? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Execute another jar in a java program
Basically I want to run an external .jar from the one I'm working on now.
I.e. I want to run foo.jar from bar.jar
I've tried using Runtime and Process to execute "java -jar foo.jar", but it opens foo.jar and then it closes immediately. Any tips?
The easiest solution (as Thorn pointed out) would be to have the jar as a build-time dependency and invoke it statically from your code:
ExternalJarMainClass.main(new String[]{"arguments", "to", "main"});
But if that is not possible, you can use a URLClassLoader to load the jar dynamically. If the jar is indeed runnable, then you can read the main class from META-INF/MANIFEST.MF and invoke main via reflection.
This is a different approach from creating a separate process, as the external code will run in the same process as your application. Perhaps this is desirable, perhaps not - that depends on the situation.
Below's a (hastily written and flawed) sample helper class that does just that.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JarRunner {
private final Method entryPoint;
public JarRunner(File jarFile) throws
ClassNotFoundException,
IOException,
NoSuchMethodException {
URL jarUrl = jarFile.toURI().toURL();
URLClassLoader loader = URLClassLoader.newInstance(
new URL[]{jarUrl});
URL manifestUrl = loader.findResource("META-INF/MANIFEST.MF");
String manifest = resourceToString(manifestUrl);
Class<?> clazz = loader.loadClass(findMainClassName(manifest));
entryPoint = clazz.getMethod("main", String[].class);
}
public void run(String[] argsToMain) throws
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
entryPoint.invoke(null, (Object) argsToMain);
}
private static String resourceToString(URL url) throws IOException {
InputStream contentStream = url.openStream();
try {
BufferedReader r = new BufferedReader(
new InputStreamReader(contentStream));
StringBuilder sb = new StringBuilder();
String line = null;
do {
line = r.readLine();
if (line != null) {
sb.append(line).append('\n');
}
} while (line != null);
return sb.toString();
} finally {
contentStream.close();
}
}
private static String findMainClassName(String manifest) {
Matcher m = MAIN_CLASS_PATTERN.matcher(manifest);
if (m.find()) {
return m.group(1);
}
return null;
}
private static final Pattern MAIN_CLASS_PATTERN =
Pattern.compile("Main-Class: (.+)");
}
Sample usage:
JarRunner jr = new JarRunner(new File("path/to/MyJar.jar"));
jr.run(new String[]{"arg1", "arg2"});
Can you run foo.jar directly? Does it have a manifest with a main method?
I am guessing that you can. So you want to launch the main method inside of a class like foo.Main
Option 1: Include foo.jar in the classpath. If you are using an IDE, then this just means adding foo.jar as a library. Now you are free to import the package (lets call the package foo) and launch your second java program from a single line of Java code:
foo.Main.main(null);
Most likely you would want to do this in a separate thread:
class FooRunner extends Thread {
public void run() {
foo.Main.main(null);
}
}
and then you would launch with this:
FooRunner secondaryApp = new FooRunner();
secondaryApp.start();
Option 2
You can load the classes in the Foo package at runtime using a class loader.
See the Javadocs for java.lang.ClassLoader and this example of a CustomClassLoader
Check java -jar foo.jar runs correctly from command line. Also ensure java is there in the path. It may be better to provide absolute path to java.exe in the arguments.
Please consider using ProcessBuilder instead of Runtime.

Categories