passing values into another java project via runtime.exec() - java

Here is my code to invoke a java project from another java project
package pkgtry;
import java.io.*;
public class Try
{
private static void runProcess(String command) throws Exception
{
Process pro = Runtime.getRuntime().exec(command);
pro.waitFor();
InputStream inputStream = pro.getInputStream();
int b = -1;
while ( (b = inputStream.read()) != -1 )
{
System.out.write(b);
}
}
public static void main(String[] args)
{
int x=10;
try
{
runProcess("javac -d . C:\\Users\\owner\\Documents\\NetBeansProjects\\input\\src\\input\\Input.java");
runProcess("java input.Input");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
This code is working perfectly. What i want is to pass an variable say 'x' from Try.java to Input.java
i would like to know the what all changes are to be made in Try.java to send the parameter and in Input.java to receive the parameter. Thanks in advance

You need to append it to command and in Input.java in main method you will have this value stored in args parameter.

Everything you want to pass to the called program is added to its commandline, like this
runProcess("java input.Input All Parameters You Want To Pass");
In Input.java you can retrieve these parameters by reading out String[] args, like this:
public class Input {
public static void main (String[] args) {
for (String s: args) {
System.out.println(s);
}
}
}
will produce
All
Parameters
You
Want
To
Pass
But you should know that this is a rather heavy-handed way to make one piece of Java code call some other piece of Java code, you can add the jar produced by the project containing Input to the Try project and instantiate the Input class directly. Calling via the command line is slow and cumbersome, and severely limits the communication between the two classes (command line parameters in one direction, an integer return value in the other direction.

Related

How to add path to file in Java args

i am working on one project and i come to the problem.
I need to run .jar over cmnd prompt and i need to put path to .properties file into the argument, for example:
java -jar myproject.jar C:\path\to\config.properties
Now i have a path to file satatic
FileInputStream in = new FileInputStream("config\\crdb.properties");
And i need to somehow put variable instead of static path and change it with argument.
Thank you.
use -D to put your System variable and use System.getProperty to get it :
java -Dpath.properties=C:\path\to\config.properties -jar myproject.jar
String pathProp= System.getProperty("path.properties");
FileInputStream in = new FileInputStream(pathProp);
Simply use args array:
public static void main(String args[]) {
try (FileInputStream in = new FileInputStream(args[0])) {
// do stuff..
}
}
if you are reading the property file from main method you can simply access command line arguments via args[] array public static void main(String args[]) simple code like below might do
public static void main(String[] args) {
String splitChar="=";
try {
Map<String, String> propertyList = Files.readAllLines(Paths.get(args[0]))
.stream()
.map(String.class::cast)
.collect(Collectors.toMap(line -> line.split(splitChar)[0],
line -> line.split(splitChar)[1]));
System.out.println(propertyList);
} catch (IOException e) {
e.printStackTrace();
}
}
or else you can pass the path as vm option
java -Dfile.path={path to config file} {JavaClassFile to execute}
and you can get the path like below (from any where in your code)
System.getProperty("file.path")
and same as in main method above you can read the property file and put it into a HashMap which I prefer

How to set/get a value from another JVM

I have a class Normal with the following code:
public class Normal {
private static String myStr = "Not working...";
private static boolean running = true;
public static void main(String[] args) {
while(running) {
System.out.println(myStr);
}
}
}
And I have another class named Injector in another project. Its purpose is to change the values of Normal even though they are not in the same JVM:
public class Injector {
public static void main(String[] args) {
String PID = //Gets PID, which works fine
VirtualMachine vm = VirtualMachine.attach(PID);
/*
Set/Get field values for classes in vm?
*/
}
}
What I want to do is change the values myStr and running in the class Normal to "Working!" and false respectively without changing the code in Normal (Only in Injector).
Thanks in advance
You'll need two JARs:
One is Java Agent that uses Reflection to change the field value. Java Agent's main class should have agentmain entry point.
public static void agentmain(String args, Instrumentation instr) throws Exception {
Class normalClass = Class.forName("Normal");
Field myStrField = normalClass.getDeclaredField("myStr");
myStrField.setAccessible(true);
myStrField.set(null, "Working!");
}
You'll have to add MANIFEST.MF with Agent-Class attribute and pack the agent into a jar file.
The second one is a utility that uses Dynamic Attach to inject the agent jar into the running VM. Let pid be the target Java process ID.
import com.sun.tools.attach.VirtualMachine;
...
VirtualMachine vm = VirtualMachine.attach(pid);
try {
vm.loadAgent(agentJarPath, "");
} finally {
vm.detach();
}
A bit more details in the article.

Java rejects public static void main method, requests public static void main method

I am trying to follow a piece of code to open and read a text file. To do this I have a package called readText. Within I build a class readLocalFile to open and read the file, and a main method to call it. Below are these two classes.
public class readFileLocal {
private String path;
public readFileLocal(String file_path){
path = file_path;
}
int readLines() throws IOException{
FileReader file_to_read = new FileReader(path);
BufferedReader lines = new BufferedReader (file_to_read);
int numberOfLines = 0;
while(lines.readLine()!= null) {
numberOfLines ++;
}
lines.close();
return numberOfLines;
}
public String[] openFile() throws IOException{
FileReader freader = new FileReader (path);
BufferedReader textReader = new BufferedReader (freader);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
int i; /* put all the lines of text from the file to the array*/
for (i=0; i<numberOfLines; i++){
textData[i] = textReader.readLine();
}
textReader.close();
return textData;
}
}
Then I have a main class to call it. The code is below:
public class fileData {
public static void main(String[] args) throws IOException{
String file_name = "F:/Testfile.exl";
try{
readFileLocal file = new readFileLocal(file_name);
String[] arylines = file.openFile();
int i;
for (i=0; i<arylines.length; i++){
System.out.println(arylines[i]);
}
}
catch(IOException e) {
System.out.println(e.getMessage());
}
}
}
When I ran it, Eclipse gave me this error message:
Error: Main method not found in class readText.fileData, please define the main method as:public static void main(String[] args) or a JavaFX application class must extend javafx.application.Application
Any idea what went wrong?
You probably should start a new project. Eclipse thinks that you are running a JavaFX program (in which case filedata should extend Application).
Just do a normal build without JavaFX.
Probably, you have declared your own String class in the same package. In this case Eclipse doesn't recognize expected java.lang.String in your main method. Edit your main method declaration as
public static void main(java.lang.String[] args)
and try to run it.
I loaded your code into my copy of Eclipse and it ran the main method without a problem. One curious thing, when I saved the file, I got a message about characters being encoded as "Cp1252" encoding rather than the expected UTF-8. I cut and paste your code into Eclipse from StackOverflow. Maybe this has something to do with the problem?
In Eclipse, you can check what is going on by selecting
Run > Run Configurations...
The "Main" tab will display what Eclipse thinks is the main method to be invoked, and other tabs will show if there are any arguments being sent in.
Also, it might be worth running
Project > Clean
for you project.
Crazy thing to check: are there any other classes with the same name?
Do you have more than one class defined on the same class document?
Another thing to check, navigate to the class document, "fileData" (really should be FileData, follow conventions because otherwise it adds to everyone's confusion who is trying to help or work with you), and right click. Does the right click give you the following?
Run As > 1) Java Application
Or does it show this?
Run As > Run Configurations...
The first case indicates it found the main method, in the second case, no main method was found.
The stuff about JavaFX can be ignored. You aren't running JavaFX according to any code I see displayed, so that issue is moot.
BTW, in your main method, you catch IOException in the try/catch, so there is no need to include "throws IOException" in the main method.

JavaExe and Java application as windows system service interactive to desktop

Request:
This is a very common problem faced by Java devs in my locale. I am really stuck for many days on this. Searched and tried a lot, read the docs. read ALL the stackoverflow questions related to JavaExe. Please only reply if you have done similar thing before and have a comprehensive answer. I would be really grateful to the community!
Senario:
I am using JavaExe to run an application as system service in desktop interactive capability.
To be exact I have an application that captures screenshots of desktops. I want it to run (as admin) on any user login so no one can stop it.
I have a myapp.jar, settings.txt and a lib dir.
I have searched alot and found JavaExe works (by watching its examples)
If anyone has a better way. Please state so.
Problem:
According to my research,
you must create a .properties file that has named like the .exe, and write "RunType = 1" in this file.
you define a static method in your main class : serviceInit()
Do I need to place any class or reference/import? How?
Edit:
My code below works as stand alone .jar and in javaExe.exe too.
It now does makes a system service and runs by as SYSTEM user. but It is NOT interactive to desktop. i.e its not showing any GUI.
package temp;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
public class Temp {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
serviceInit();
}
public static boolean serviceInit(){
new Thread(){
public void run(){
Integer i = 0;
while(i < 999999999){
JOptionPane.showMessageDialog(null,i);
i++;
}
}
}.start();
return true;
}
}
And I dont think that bundling the .jar, lib directory and settings.txt into one .exe is possible?
you should have in your case :
public class MyApp_ServiceManagement
{
static boolean isMsgToDisplay = false;
/////////////////////////////
public static boolean serviceInit()
{
(new Thread()
{
public void run()
{
for(int i=0;i < 6;i++)
{
try { sleep(5*1000); }
catch(Exception ex) {}
isMsgToDisplay = true;
}
}
}).start();
return true;
}
/// is Data ready to be send to the UI ?
public static boolean serviceIsDataForUI()
{
return isMsgToDisplay;
}
/// Data to be send to the UI
public static Serializable serviceDataForUI()
{
isMsgToDisplay = false;
return "hello, I am an interactive Service";
}
}
and for the UI part :
public class MyApp_TaskbarManagement
{
/// To show (or not) the icon in tray
public static boolean taskIsShow()
{
return false;
}
/// Receive the message from Service
public static void taskDataFromService(Serializable data)
{
JOptionPane.showMessageDialog(null, data);
}
/// descr of UI
public static String[] taskGetInfo()
{
return new String[]
{
"UI part of Service"
};
}
}
the main() method is never called in service mode (except one particular case), but if you want keep your main() method you must put a call to main() in serviceInit().
Put serviceInit() in your main class or in another class named XXX_ServiceManagement where XXX is the name of your main class.
Then, serviceInit() must return before a 30 seconds delay.
Don't put a infinite loop, ... in it.
Put your code in a thread, and start it from serviceInit() (or main)
That answer to your problem?

Java: How to determine startup arguments without the main line access?

I'm curious to know if it is possible to determine the startup arguments of a Java application when you don't have access to the arguments array from the main line.
public static void main(String[] args)
{
// Invokes my code without providing arguments.
mycode();
}
public static void mycode()
{
// Attempting to determine arguments here.
// TODO GetArgs()
}
I'm in this situation by doing some plugin work and the core application does not provide a list of startup arguments. Any thoughts?
Not unless the plugin is given them, but that kind of goes without saying (at least in Java).
If you need to set some options specifically for your plugin, but can't access the command line, there are at least two options:
Options file (several mechanisms)
Set system params on the command line
For the second option, just use the normal -D option and namespace the param name, like:
java -Dcom.davelnewton.plugins.foo.bar=anOptionValue etc...
Retrieve them via System.getProperty(anOptionName) or one of its cousins.
IMO an options file is a better (ahem) option, even if you're specifying the file path on the command line, but if you only have an option or two, maybe not--just depends.
Pass the arguments to the function?
public static void main(String[] args)
{
mycode(args);
}
public static void mycode(String[] args)
{
String arg1 = args[0];
}
You could do:
public static void main(String[] args)
{
System.setProperty("cmdArgs", args);
mycode();
}
public static void mycode()
{
// Attempting to determine arguments here.
String[] args = System.getProperty("cmdArgs");
}

Categories