My goal is to use Apache CLI with an executable jar file to read in a text file, perform string manipulations, and then write to a CSV. You would execute the tool in the terminal like this:
$ java -jar my-tool-with-dependencies.jar -i input.txt -o output.csv
I've written tests for this functionality and those tests are passing. The test input text file is located in src/test/resources/. The following test is passing:
#Test
public void testWordockerWriteCsvFileContents() {
// Make sure the csv file contains contents
Wordocker w = new Wordocker();
String intext = "/textformat/example_format.txt";
String outcsv = "/tmp/foo.csv";
w.writeCsvFile(intext, outcsv);
try {
Reader in = new FileReader(outcsv);
Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(in);
for (CSVRecord record : records) {
assertTrue(record.toString().length() > 0);
}
} catch(FileNotFoundException e){
assertTrue(false);
} catch(IOException e) {
assertTrue(false);
}
File file = new File(outcsv);
if (file.exists()) {
file.delete();
}
}
We I compile my jar files with dependencies using mvn clean compile assembly:single then I raise the following FileNotFoundException:
// Get file from resources folder
URL resourceURL = ParseDoc.class.getClassLoader().getResource(fileName);
if (resourceURL == null) {
throw new FileNotFoundException(fileName + " not found");
}
file = new File(resourceURL.getFile());
This leads me to believe that there is an issue with where ParseDoc.class.getClassLoader().getResource(fileName); is looking for the file. I'm aware of related questions which have been asked. Related questions are the following:
Strange behavior of Class.getResource() and ClassLoader.getResource() in executable jar
What is the difference between Class.getResource() and ClassLoader.getResource()?
MyClass.class.getClassLoader().getResource(“”).getPath() throws NullPointerException
this.getClass().getClassLoader().getResource(“…”) and NullPointerException
getResourceAsStream returns null
None of these questions appear to ask about how to use an executable jar with Apache CLI. I think the basic issue is that the filepath given by my command line argument cannot be found by URL resourceURL = ParseDoc.class.getClassLoader().getResource(fileName);.
Please let me know what you think. Thank you for your time.
I'm posting this as answer as well after discussion via comments:
Classloader.getResource() is only fetching files that are packaged as part of the Jar-file or located in the classpath-folders.
For reading a normal file you would use something like your first example, i.e. FileReader or FileInputStream or simply pass a java.io.File depending on what the library that you are trying to use supports.
I'm trying to decompress a rar file, using the runtime but it doesn't works!, just open a prompt saying that can't find the file
this is the code for it:
try {
Runtime.getRuntime().exec("C:\\Program Files (x86)\\WinRAR\\WinRAR.exe X *ok*.rar F:\\");
} catch (IOException ex) {
System.out.println(ex);
}
also i've used the processbuilder and that's worse, dosen't do anything ¬_¬
ProcessBuilder b = new ProcessBuilder("C:\\\\Program Files (x86)\\\\WinRAR\\\\WinRAR.exe X *sok*.rar F:\\");
here is where i find the information about the winrar
looks like path issue.( C:\Program Files (x86)\WinRAR\WinRAR.exe X ok.rar F:\")
"\" may be used along with roots eg(c:\, D:\) and then follows "\"
D:\programfiles\winar
I have a program that uses a file named list.txt to populate an ArrayList with its contents and then get a random line.
Here's the part that loads the file:
public class ReadList {
private Scanner f;
public void openFile(){
try{
f = new Scanner(new File("list.txt"));
}catch(Exception e){
System.out.println("File not found!");
}
}
However, it doesn't work when running it from a .jar file. I put the txt in the same directory and used f = new Scanner(new File("./list.txt")); yet it didn't work. I also tried some stuff I have found online but all I could manage to do is a) get a full path of the .jar with .jar included(/home/user/java/program.jar), and b) get a full path of the directory but without the / at the end(/home/user/java), which is a problem since I want this program to work on both Windows and Linux, therefore I can't simply do ("/home/user/java" + "/list.txt"), since Windows uses backslashes in paths.
So what's the simple way to just target the specific file(which will always be called list.txt) no matter which directory the file's in, as long as it's in the same place as the .jar?
Use this:
String filePath = System.getProperty("user.dir") + File.separator + "file.txt";
filePath will now contain the full path of file.txt which will be in the same dir as your jar.
How could I run a local jar file from a java program?
The jar file is not in the class-path of the Java caller program.
I suggest you use a ProcessBuilder and start a new JVM.
Here is something to get you started:
ProcessBuilder pb = new ProcessBuilder("/path/to/java", "-jar", "your.jar");
pb.directory(new File("preferred/working/directory"));
Process p = pb.start();
Process proc = Runtime.getRuntime().exec("java -jar Validate.jar");
proc.waitFor();
// Then retreive the process output
InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();
byte b[]=new byte[in.available()];
in.read(b,0,b.length);
System.out.println(new String(b));
byte c[]=new byte[err.available()];
err.read(c,0,c.length);
System.out.println(new String(c));
First, the description of your problem is a bit unclear. I don't understand if you want to load the classes from the jar file to use in your application or the jar contains a main file you want to run. I will assume it is the second.
If so, you have a lot of options here.
The simplest one would be the following:
String filePath; //where your jar is located.
Runtime.exec(" java -jar " + filepath);
Voila...
If you don't need to run the jar file but rather load the classes out of it, let me know.
Could something like the following be useful?
http://download.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html
Another way to do on windows is:
Runtime.getRuntime().exec("cmd /c start jarFile");
this way you can set priority of your process as well (normal/low/etc)
You can run a jar file from where ever you want by using only this one line code.
Desktop.getDesktop().open(new File("D:/FormsDesktop.jar"));
where
new File("your path to jar")
Hope it helps.
Thanks.
Add jar library to your project
Import main class (see manifest in jar file)
Invoke static method main with arguments
String args[] = {"-emaple","value"};
PortMapperStarter.main(args);
To run an executable jar from inside your java application, you can copy the JarClassLoader from https://docs.oracle.com/javase/tutorial/deployment/jar/examples/JarClassLoader.java
Use it like this. In this snippet, jarUrl is the URL to download the jar from, for example file:/tmp/my-jar.jar and args is the array of strings you want to pass as command line arguments to the jar.
JarClassLoader loader = new JarClassLoader(jarUrl);
String main = loader.getMainClassName();
loader.invokeClass(main, args);
Keep in mind that you're now inserting someone else's binary into your code. If it gets stuck in an infinite loop, your Thread hangs, if it calls System.exit(), your JVM exits.
This is my appriach, which I consider is more complete:
public static Process exec(String path, String filename) throws IOException {
String javaHome = System.getProperty("java.home");
String javaBin = javaHome +
File.separator + "bin" +
File.separator + "java";
ProcessBuilder pb = new ProcessBuilder(javaBin, "-jar", path+filename);
return pb.start();
}
1) Set the class path from environment variables
2) Go to the folder where your jar file exists
3) Run the following commands through command prompt
java -jar jarfilename
I need some help with using the following code to modify and existing jar file:
String command = "cmd /c jar uf " + dirToModify + " " + Main.getMain().outputLocate.getSelectedFile();
try {
Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
dirToModify = "C:\\Users\\Me\\Desktop\\myfile.jar"
Main.getMain().outputLocate.getSelectedFile() = "C:\\Users\\Me\\Desktop\\myfolder"
Basically I want to add the files/folders from myfolder to myfile.jar but with the above code it will add a shortcut to my C: drive not the files from myfolder.
Also I did look at other posts but none help me with this problem.
Any help with this would be greatly appreciated.
I'd suggest, first checking, if adding one file, at a time, is working with this code. This will make clear if problem is in 'folder addition' or 'file addition'.
If file addition doesn't work, your basic jar update logic is broken. So you can ask for solution to that problem.
If file addition works, try recursively adding all files from destination folder.