Creating and using .exe in JAR - java

I have some code written in Java that executes some .exe file. It first creates a temporary file from where it executes it and then destroys that file after the execution is done.
The only problem with this is, it requires the executable file to be in the same package as that of the class having main function. I want to place and access my .exe file from other locations as well because while creating the JAR file of my project it never executes that exe file.
Is there some other way by which my .exe file can also be a part of my JAR file irrespective of its location in my project?
Here's the code :
package com.web.frame;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
//import java.net.URL;
public class Test{
public void Test1(String fileAddr,String filename, String destFilenam) throws Exception {
// Place .exe into the package folder.
InputStream src =this.getClass().getResourceAsStream("DECRYPT.exe");
if(src!=null) {
File exeTempFile = File.createTempFile("dspdf", ".exe");
byte []ba=new byte[src.available()];
src.read(ba,0,ba.length);
exeTempFile.deleteOnExit();
FileOutputStream os=new FileOutputStream(exeTempFile);
os.write(ba,0,ba.length);
os.close();
String hello=exeTempFile.getParent();
System.out.println("Current Directory Of file : "+hello);
String hello1=exeTempFile.getName();
System.out.println("Full Name Of File : "+hello1);
int l=hello1.length();
l=l-4;
char[] carray=hello1.toCharArray();
String s = new String(carray,0,l);
System.out.println(s);
String param="cmd /c cd "+hello+" && "+s+" d 23 11 23 "+fileAddr+"\\"+filename+" "+destFilenam;
Runtime.getRuntime().exec(param);
Runtime.getRuntime().exec("c:\\Program Files\\VideoLAN\\VLC\\vlc.exe "+hello+"\\"+destFilenam);
Runtime.getRuntime().exec("cmd /c del"+hello+"\\"+destFilenam);
}
else
System.out.println("Executable not found");
}
}

The maximum you can do is place your exe anywhere in your classpath. Ensure that the jar's manifest has a classpath element. Then you should be able to access the exe by saying Test.class.getResourceAsStream("")
So create a folder, put the exe into that folder and include the folder in your classpath.

Related

Trying to compile and run c++ code with java code

I was trying to compile and run a c++ program from a java program, I made a .bat file having compilation and execution command, The code for making .bat file works fine, but code to open the .bat file doesn't work. It says "g++ is not recognized as an internal/external command", but if I open .bat file manually, it works fine. please help me with the code:
import java.io.*;
import java.util.*;
import java.lang.*;
public class Batch
{
FileOutputStream fos;
DataOutputStream dos;
public Batch()
{
}
public void createBat() throws Exception
{
File file=new File("M:\\AV\\compile_Execute.bat");
fos=new FileOutputStream(file);
dos=new DataOutputStream(fos);
dos.writeBytes("#echo off");
dos.writeBytes("\n");
dos.writeBytes("g++ main.cpp -o main.exe -lmingw32 -lSDL2main -lSDL2 & main.exe");
fos.close();
}
public void executeBat() throws Exception
{
String[] command = {"cmd.exe", "/C", "Start", "M:\\AV\\compile_execute.bat"};
Process p = Runtime.getRuntime().exec(command);
}
}
What happens here is that you messed up with the path, because the file is located in another drive, you cannot just use the path or go back a folder using ".."
Firstly, go to the biggest directory
cd "C:\"
Then, change drive
M:
Note that to change directoy you must be in the drive biggest folder and that to change drives, you must use the format letter:
These two steps can be simplified to cd D:
Next:
cd "M:\\AV\\"
Finally:
compile_execute.bat
Merging it, I would use this instead of just a path: cd /D M:\\AV\\ compile_execute.bat
I suggest reading about MS-DOS.
Thanks for the comment related to not being able to change directory to a file.

Incorrect Absolute File Path

I need a relative path for a csv file I have called GameDatabase.csv. It is in the same folder as my main method which are both in zzz folder.
The file kept turning up not found so I decided to print the absolute path
String db = "GameDatabase.csv";
File file = new File(db);
String path = file.getAbsolutePath();
System.out.print("\npath " + path);
The output is
path xxx\IdeaProjects\CISC_231\FinalProject\GameDatabase.csv
However the path that I am looking for is
xxx\IdeaProjects\CISC_231\FinalProject\zzz\GameDatabase.csv
Why is the absolute file path printing this out? What is going on in the background and how can I change it to get the correct file path?
That is because, when you look for a file, the default directory is the project one (in this case FinalProject)
I structured the project as follows
Main.java and GameDatabase.csv are both in src
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
System.out.println(new File("GameDatabase.csv").exists()); // the file does not exist in FinalProject folder
System.out.println(new File("src/GameDatabase.csv").exists()); // but exists in FinalProject/src
System.out.println(Main.class.getClassLoader().getResourceAsStream("GameDatabase.csv").toString()); // this is a solution to look for the file within the classpath
}
}
The output is
false
true
java.io.BufferedInputStream#7852e922
String db = "GameDatabase.csv";
File file = new File(db)
You can create a File object representing a file that doesn't actually exist. What you have done is creating a File object representing the file "GameDatabase.csv" in the current working directory (this file does not exist) and then you printed the absolute path it would have if it existed.

How to specify path of a file in java/terminal on Hadoop?

I am running a task on Hadoop2:
$hadoop jar hipi.jar "/5" "/processWOH" 1
hipi.jar: the jar file name
"/5": the input folder name
"/processWOH": the output folder name
I am getting and exception regarding the path /localhost:9000/5/LC814000.tif:
Error: java.io.FileNotFoundException: /localhost:9000/5/LC814000.tif (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at ProcessWithoutHIPI.ProcessRecordReaderWOH.getCurrentKey(ProcessRecordReaderWOH.java:81)
at ProcessWithoutHIPI.ProcessRecordReaderWOH.getCurrentKey(ProcessRecordReaderWOH.java:1)
at org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.getCurrentKey(MapTask.java:507)
at org.apache.hadoop.mapreduce.task.MapContextImpl.getCurrentKey(MapContextImpl.java:70)
at org.apache.hadoop.mapreduce.lib.map.WrappedMapper$Context.getCurrentKey(WrappedMapper.java:81)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:340)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:167)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1548)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:162)
I think ( I am not sure) the problem with the extra "/localhost:9000" added to the path, but I don't know how it is added ( By hadoop, java code, ...).
Notice: this jar file is running fine outside of hadoop but in hadoop (hdfs) it is not
Any help is appreciated
Update:
As I discovered later that "/5" folder is searched inside the local system not inside hdfs and if I create a folder in the local file system with name "localhost:9000" under root i.e. /localhost:9000 and put "/5" the code will run, but in this case the data is taken outside from hadoop like if I am not using hadoop at all.
So is this a mistake in programming i.e. I should use hadoop io packages instead of java io packages to deal with hdfs instead of local filesystem, or it is another problem.?
The default directory of your hdfs is /localhost:9000/, hadoop can not find your input file there; just past it in /localhost:9000/:
$hadoop fs -put $LOCAL_PATH_OF_INPUT_FILE:/5 /localhost:9000/
$hadoop jar hipi.jar "/5" "/processWOH" 1
Good luck!
The problem is as I said earlier was that Java IO (i.e. File Class, Path class,...) treats paths as in local file system whereas Hadoop Io (FileSystem class, Path class,...) treats paths as in HDFS.
Please have a look here:
read/write from/in HDFS
Using FileSystem API to read and write data to HDFS
Reading data from and writing data to Hadoop Distributed File System (HDFS) can be done in a lot of ways. Now let us start by using the FileSystem API to create and write to a file in HDFS, followed by an application to read a file from HDFS and write it back to the local file system.
Step 1: Once you have downloaded a test dataset, we can write an application to read a file from the local file system and write the contents to Hadoop Distributed File System.
package com.hadoop.hdfs.writer;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.util.Tool;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.ToolRunner;
public class HdfsWriter extends Configured implements Tool {
public static final String FS_PARAM_NAME = "fs.defaultFS";
public int run(String[] args) throws Exception {
if (args.length < 2) {
System.err.println("HdfsWriter [local input path] [hdfs output path]");
return 1;
}
String localInputPath = args[0];
Path outputPath = new Path(args[1]);
Configuration conf = getConf();
System.out.println("configured filesystem = " + conf.get(FS_PARAM_NAME));
FileSystem fs = FileSystem.get(conf);
if (fs.exists(outputPath)) {
System.err.println("output path exists");
return 1;
}
OutputStream os = fs.create(outputPath);
InputStream is = new BufferedInputStream(new FileInputStream(localInputPath));
IOUtils.copyBytes(is, os, conf);
return 0;
}
public static void main( String[] args ) throws Exception {
int returnCode = ToolRunner.run(new HdfsWriter(), args);
System.exit(returnCode);
}
}
Step 2: Export the Jar file and run the code from terminal to write a sample file to HDFS:
[training#localhost ~]$ hadoop jar HdfsWriter.jar com.hadoop.hdfs.writer.HdfsWriter sample.txt /user/training/HdfsWriter_sample.txt
Step 3: Verify whether the file is written into HDFS and check the contents of the file:
[training#localhost ~]$ hadoop fs -cat /user/training/HdfsWriter_sample.txt
Step 4: Next, we write an application to read the file we just created in Hadoop Distributed File System and write its contents back to the local file system:
package com.hadoop.hdfs.reader;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class HdfsReader extends Configured implements Tool {
public static final String FS_PARAM_NAME = "fs.defaultFS";
public int run(String[] args) throws Exception {
if (args.length < 2) {
System.err.println("HdfsReader [hdfs input path] [local output path]");
return 1;
}
Path inputPath = new Path(args[0]);
String localOutputPath = args[1];
Configuration conf = getConf();
System.out.println("configured filesystem = " + conf.get(FS_PARAM_NAME));
FileSystem fs = FileSystem.get(conf);
InputStream is = fs.open(inputPath);
OutputStream os = new BufferedOutputStream(new FileOutputStream(localOutputPath));
IOUtils.copyBytes(is, os, conf);
return 0;
}
public static void main( String[] args ) throws Exception {
int returnCode = ToolRunner.run(new HdfsReader(), args);
System.exit(returnCode);
}
}
Step 5: Export the Jar file and run the code from terminal to write a sample file to HDFS:
[training#localhost ~]$ hadoop jar HdfsReader.jar com.hadoop.hdfs.reader.HdfsReader /user/training/HdfsWriter_sample.txt /home/training/HdfsReader_sample.txt
Step 6: Verify whether the file is written back into local file system:
[training#localhost ~]$ hadoop fs -cat /user/training/HdfsWriter_sample.txt
FileSystem is an abstract class that represents a generic file system. Most Hadoop file system implementations can be accessed and updated through the FileSystem object. To create an instance of the HDFS, you call the method FileSystem.get(). The FileSystem.get() method will look at the URI assigned to the fs.defaultFS parameter of the Hadoop configuration files on your classpath and choose the correct implementation of the FileSystem class to instantiate. The fs.defaultFS parameter of HDFS has the value hdfs://.
Once an instance of the FileSystem class has been created, the HdfsWriter class calls the create() method to create a file in HDFS. The create() method returns an OutputStream object, which can be manipulated using normal Java I/O methods. Similarly HdfsReader calls the method open() to open a file in HDFS, which returns an InputStream object that can be used to read the contents of the file.
The FileSystem API is extensive. To demonstrate some of the other methods available in the API, we can add some error checking to the HdfsWriter and HdfsReader classes we created.
To check whether the file exists before we call create(), use:
boolean exists = fs.exists(inputPath);
To check whether the path is a file, use:
boolean isFile = fs.isFile(inputPath);
To rename a file that already exits, use:
boolean renamed = fs.rename(inputPath, new Path("old_file.txt"));

How to build jar artifact so at run-time it will be able to read packed files?

At run-time application successfully files at project's root. All works fine when executing project in IntelliJ but when built jar artifact by IntelliJ executed in Windows environment it has troubles locating/reading files although they reside in root of jar file. How to fix it?
UPDATE
I am using Jersey framework. I read file from root path like that:
package example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
#Path("/monitor")
public class MonitoringPage {
#GET
#Produces("text/html")
public String getMonitoringPage() throws IOException {
String page, line;
page = "";
BufferedReader br = new BufferedReader(new FileReader("MonitoringPage.htm"));
while((line = br.readLine()) != null){
page += line + "\r\n";
}
br.close();
return page;
}
}
My jar has MonitoringPage.htm in it's root but it cannot find it for some strange reason.
I am running jar with bat script:
java -jar "Rs.jar"
.
JAVA_HOME=C:\Program Files\Java\jdk1.7.0_51
Path=.......**C:\Program Files\Java\jdk1.7.0_51\bin**
Don't read it as a file from the file system (as is what happens when you use File, FileReader or many of its FileXxx variants). Once you package the jar, the file will no long be in the system file location you are expecting
Instead read it as a resource via an URL. You can use:
MonitoringPage.class.getResourceAsStream("/MonitoringPage.htm") which will return an InputStream.
From that InputStream you can just do something like
InputStream is = MonitoringPage.class.getResourceAsStream("/MonitoringPage.htm");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
Note: this is all assuming you have the file at the root of the classpath (which it looks like from your image). The / in the front of the path will bring the search to the root of the classpath. So just use the path to the file that's relative to the root

Java - FilenotfoundException for reading text file

by running this...
File file = new File("Highscores.scr");
i keep getting this error, and i really don't know how to get around it.
the file is currently sitting in my source packages with my .java files.
I can quite easily read the file by specifying the path but i intend to run this on multiple computers so i need the file to be portable with the program.
this question isnt about reading the text file but rather specifying its location without using an absolute path .
ive searched for the answer but the answers i get are just "specify the name" and "specify the absolute path".
id post an image to make it more clear but i dont have the 10 rep to do so :/
how do i do this?
cheers.
The best way to do this is to put it in your classpath then getResource()
package com.sandbox;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
public class Sandbox {
public static void main(String[] args) throws URISyntaxException, IOException {
new Sandbox().run();
}
private void run() throws URISyntaxException, IOException {
URL resource = Sandbox.class.getResource("/my.txt");
File file = new File(resource.toURI());
String s = FileUtils.readFileToString(file);
System.out.println(s);
}
}
I'm doing this because I'm assuming you need a File. But if you have an api which takes an InputStream instead, it's probably better to use getResourceAsStream instead.
Notice the path, /my.txt. That means, "get a file named my.txt that is in the root directory of the classpath". I'm sure you can read more about getResource and getResourceAsStream to learn more about how to do this. But the key thing here is that the classpath for the file will be the same for any computer you give the executable to (as long as you don't move the file around in your classpath).
BTW, if you get a null pointer exception on the line that does new File, that means that you haven't specified the correct classpath for the file.
As far as I remember the default directory with be the same as your project folder level. Put the file one level higher.
-Project/
----src/
----test/
-Highscores.scr
If you are building your code on your eclipse then you need to put your Highscores.scr to your project folder. Try that and check.
You can try to run the following sample program to check which is the current directory your program is picking up.
File f = new File(".");
System.out.println("Current Directory is: " + f.getAbsolutePath());

Categories