I am trying to run a linux based executable called src2srcml in my JFrame GUI that takes a source file (C, C++, Java) and converts it to an XML file to be used later. My GUI successfully uses the JFileChooser to locate and select the source file.
I'm currently trying to use the Runtime.getRuntime().exec() function to run the executable but so far nothing is happening. I can run it from the command line using the commands "bash-4.1$ ./src2srcml --position sum_avg.c -o hooray.c.xml", which takes the source file sum_avg.c, converts it to XML in a new file hooray.c.xml but when I try the exact same commands in Runtime.getRuntime().exec() nothing happens. I'm not particularly familiar with the Runtime.getRuntime().exec() or ProcessBuilder classes. Do I need to navigate to where the executable is first? I also tried including the path in the first parameter, the call to the executable its self but that didn't work either.
//--- 'Run Source Code' Button---//
JButton btnRunSourceCode = new JButton("Run Source Code");
btnRunSourceCode.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(filePath == null){
textArea.setText("Please Load a source file (C, C++, Java)");
}
try{
textArea.setText("Converting Source Code to XML");
String[] commands = {"./src2srcml", "--position ", selectedFile.getName(), " -o targetFile.xml"};
Process src2XML = Runtime.getRuntime().exec(commands);
src2XML.waitFor();
}
catch(Exception exc){/*src2srcml Fail*/}
}
});
btnRunSourceCode.setBounds(612, 39, 156, 25);
contentPane.add(btnRunSourceCode);
Currently the executable is in the workspace of my project (Eclipse). when I get everything working I would like to compile the whole program into a single executable so that the src2srcml is embedded into my executable and isn't required separately. Is this possible?
Thanks in advance for any ideas!
I am not familiar with Unix, but, don't you need to call this through the unix shell, perhaps by calling bash or other shell commands with your command array? For example the answers here
Other problems
Threading: you are currently asking your process to run on the Swing event thread, which if successful will cause your GUI to completely freeze and be non-usable until the process ends. You should make all calls like this background to the GUI thread such as can be achieved by using a SwingWorker object.
GUI mistakes: You're calling setBounds on your JButton and adding to a container that probably uses a null layout, which marks this as code from a Swing newbie, since this means that you're making inflexible GUI's that are very difficult to upgrade or enhance. Use the layout managers to place your components. The Swing layout manager will help show you how to fix this.
Regarding
when I get everything working I would like to compile the whole program into a single executable so that the src2srcml is embedded into my executable and isn't required separately.
No, this is likely not possible, unless you include the file in your jar as well as code to de-zip it.
Related
So I have this code that works fine, it launch the .jar file from another machine that I have configure in my pc as a red ubication
Runtime.getRuntime().exec("java -jar Z:\\AAA\\BBB\\CCC\\ZZZ.jar");
But now I want to launch the .jar from that external path without using the shortcut before (so I can launch it with this code in a machine that dont have that red ubication configured)
Runtime.getRuntime().exec("java -jar MMM\\NNN LLL\\OOO\\AAA\\BBB\\CCC\\ZZZ.jar");
But doent work (I can access and open the file manually without a problem).
When I enter the java -jar MMM\\NNN LLL\\OOO\\AAA\\BBB\\CCC\\ZZZ.jar in the Command prompt it return me Error: Unable to access jarfile MMM\NNN, so perhaps one problem is that the path have a space in the folder name, but I think that may be something else too.
The question is, if the problem is the space, how I can solve it? I cant find a way. And in the other hand, how I can run it in another machine? I have to use that red ubication IP in some way instead?
PD: Using this code, it return me true
File f = new File("\\\\MMM\\NNN LLL\\OOO\\ZZZ.jar");
System.out.println(f.exists()); //--> true
So looks like the spaces dont interfere in the path (the four "\" doesnt seem to do anything in the tests when launching)
I have heard other people having such problems. The main reason for that is that probably Java exec method is not network (SMB) aware. So it doesn't even try to open from the network.
Anyway running the code like that from the network might not be the best solution. First of all the network might be unavailable, or the java file coming might be corrupted. If you want to do it properly you have several options:
Simple option that can work:
Create a bat file that works and exec that one - you can even copy the file locally first to make sure it is available first (if it is big and the network fails)
A better solution :
Use java to copy the file to the working directory and execute it from there.
A plus to do it like that by downloading is that you can maintain a version of the file (hash?) so you don't download it if it is the same. Or you can have fallback - execute the last downloaded version if the network drive is unavailable.
Use a local maven repository and dependency for that jar :)
This way it will keep the version of the jar locally and won't have to download it every time. It will also download a new version if available and the code will be more mainstream (for example not platform / pc dependent)
The answer give by #MadProgrammer works fine!
ProcessBuilder builder = new ProcessBuilder("java", "-jar", "MMM\\NNN LLL\\OOO\\AAA\\BBB\\CCC\\ZZZ.jar");
try {
builder.start();
} catch (IOException e) {
e.printStackTrace();
}
Lot of thanks! In any case going to check the ideas posted by Veselin Davidov
I have two visual studio projects (for different purpose... they act on two different hardware) and also, I have a Java project that have control on something else. I am working in windows. My question is that how can I write a script (like shell script) to control different projects from a single program. More specifically, suppose I want to do something like this: execute project 1 with parameters x1,x2,...,xn, then execute project 2 with parameters y1,y2,...,yn, then execute project 1, then project 3, & so on...
Is there any tutorial or short description that I can follow to implement my concept?
There's a myriad of options/scripting languages/... to achieve this, but if you just want to run a bunch of exes then a simple windows batch file will do just fine:
#echo off
set my_exe=c:\path\to\my.exe
set my_other_exe=c:\path\to\my_other.exe
%my_exe% a
%my_exe% a b c
%my_other_exe% x
%my_other_exe% x y z
pause
Save this with your favourite editor with a .bat extension and run by double-clicking. The lines with set create variables so you don't have to paste the full path to your exes the whole time. The lines referring to those variables will invoke the executables aith the argumenst that come after it. Search the internet for 'batch file examples' or something like that and you will quickly find all the info needed.
This question already has answers here:
Can I set Java max heap size for running from a jar file?
(8 answers)
Closed 9 years ago.
I am trying to create a jar file that will execute my game with just a click. My game exceeds java's default allocated heap memory so I have to run my code with -Xmx1000m. I've been researching online and unfortunately there doesn't seem to be a way to tell a jar file to fun my code with more than the default memory. Instead I created another class that will use runtime to compile my code from within another main method and created a jar file using this:
import java.io.*;
public class RuntimeExec{
public static void main(String[] args){
try
{
Process process = Runtime.getRuntime().exec("java -Xmx1000m Controller");
process.waitFor();
int exitCode = process.exitValue();
if(exitCode == 0) { /* success*/ }
else { /*failed*/ }
}
catch (Exception e)
{e.printStackTrace();}
}
}
This works however I think it only works because it runs my existing class in the folder and not the one I stored in the jar. Is there a way so that the jar will run a class within in or combine two different jars that will allow me to get around the memory heap problem?
The entire solution to providing an easy install for users is to deploy the app. using Java Web Start. It can set RAM for an app., and also install a desktop shortcut to launch it. JWS is much more robust than a (poorly implemented) call to exec.
However if JWS is not for some reason suitable for this app., see IWantToBeBig for a hack that will cause a Jar to have enough memory (similar to how you use exec above, but slightly more robust in using ProcessBuilder to relaunch the app. that does not have enough memory).
Organizing the desktop shortcut to allow the user to launch it with a click, is left as an exercise for the reader.
There are many ways of doing it:
As you mentioned, by having another Jar file which triggers your game file
As #Perception mentioned, have a batch file which will start your game. But be careful, if downloaded from say Net, the user will have to set permissions for the script to be runnable
Build an installer. On Mac, using the Oracle Java App bundler for Java 7, Apple App bundler for Java 6 build the .app file. You still cant redistribute it as the necessary permissions wont be set. Build a dmg for the app file. This can be used for distribution.
A similar installer for Windows
The third technique would be the best, as you can then package the dependencies well, set all JVM arguments etc
I have a basic, simple and maybe stupid question, but how do I implement that I can drag a file onto my java program and open it?
I searched really long for this basic question.....
As long as I found out you can't implement dragging it onto the .jar, because its not executable. You have to create a .exe, which also open your .jar, but that's all! I would really like to know how :)
A keyword would be enough, if I can get the answer through searching this keyword.
Thanks, Leander
//Edit: I may have expressed things a little bit complicated.
Later i want to have a shortcut on, for example, the desktop where i can drag any file on the shortcut and the programm opens with the file(it will, at this point) only move it to a special location.
I donĀ“t know how the code for this would be, I even don't know how to google for this (I only get questions how to implement "open with" with the answer Desktop.open(File f)).
For windows only:
option 1:
make a batch file into the directory of your jar file (or anywhere you like but then you need to adjust the path, you can also make a shortcut from the batch file).
#ECHO OFF
start java -jar %~dp0MYAPP.jar %1
option 2:
Make a shortcut (right click - new - shortcut)
Enter into the location "java -jar C:\path\to\myapp.jar"
drag and drop will work if your jar accepts filename as a parameter
public class Main {
public static void main(String[] args) {
if (args.length == 0)
System.out.println("No arguments");
else
System.out.println("1st argument: " + args[0]);
}
}
The place to start reading is the JDK 6 documentation on Drag and Drop. Or else you can start directly with the Drag and Drop tutorials.
If you want to create a desktop icon that will open your app when you drop a file on it, this depends on the OS. I think that Launch4j will support this, although I haven't used it in this way.
On window you can create .bat file, and if you DnD on that file you get filename as fisrt parameter
so code
echo %1
pause
writes the filename out, so you can start you java program like
java -jar myApp.jar MyAppClass %1
I'm pretty new to Perl but have been programming in java for several months now (coming from a C++ background). I wrote a Perl script that parses some data logs and now the customer I'm working for wants a GUI. The GUI has been created as a java applet (using Netbeans) and I would like to "embed" the perl script inside its jar file as a default safety feature. Multiple updates are expected for the perl script later in the future, so I want to set it up so that all the user has to do when an update comes along is define a new file path to the latest perl script through the GUI. I've already implemented this functionality with a file browser and everything works fine.
The problem I'm running into is something very simple that's probably not very hard for someone with more java experience. Just in case one of the updated perl scripts they receive in the future doesn't work properly, I want them to be able to use the default "embedded" script if they have to resort to that. When I'm running the applet through Netbeans, everything works perfectly however when I try and run the jar file from the command line, the program returns an error saying it cannot find the file. I might not be using the correct terminology to search for a solution to this problem, but I would like to be able to have my jar file execute the embedded perl script at runtime. Any suggestions are appreciated. I've tried placing the perl file in the same package as the java files and calling for the script by its filename alone, but that was a no go.
You can access any file in the jar as a classpath resource, but the problem you're going to have is users may not have a perl interpreter installed.
EDIT: Since you've mentioned that users will have a Perl runtime, then this is doable. You can try piping the contents of the file using Process.getOutputStream() or just copy the contents to a temp file with File.createTempFile() and pass that file name as an argument to the perl interpreter.
I have the same problem, here's how I solved it based on Josh and Jiggy's discussion above. First look for the file in src/main/resources/perl (so it works in Eclipse). If it does not exist then copy the Perl file from the perl directory inside the jar to src/main/resources/perl. I building with Maven so using the src/main/resources/perl directory means when I build the jar, Maven automatically includes the perl directory in the jar.
This is a similar strategy to the one used to load resources from jars such as properties files.
I am using this approach because I have a multi-module Maven project when each submodule builds a jar. We have one that does general information extraction, then another one that specializes that module for a particular client. The Perl code lives inside the general module, but it is needed in the specialized one. Copying files between modules in Maven is rather awkward, so it is easier just to put it in resources, then let the Java code solve the problem.
See this related question for a good answer of an alternative approach to embedding native code such as C in jars.
The code looks like this (I'm using Apache Commons IO):
public class PerlTableParser {
private static final String RESOURCES_DIR = "src/main/resources";
private static final String LIB_PATH = RESOURCES_DIR + "perl/";
private static final String PERL_PARSER = "perl/parser.pl";
private static final String PERL_CMD = String.format("perl -I %s %s",
LIB_PATH, RESOURCES_DIR + PERL_PARSER);
public PerlTableParser() {
File perlCodeDir = new File(LIB_PATH);
if (!perlCodeDir.exists()) {
perlCodeDir.mkdirs();
}
File perlParserFile = new File(RESOURCES_DIR, PERL_PARSER);
try {
if (!perlParserFile.exists()) {
FileUtils.copyInputStreamToFile(getClass().getClassLoader()
.getResourceAsStream(PERL_PARSER), perlParserFile);
}
} catch (IOException e) {
MyLogger.logger.error(
"Failed to copy Perl code to local directory " + e, e);
}
}