Ok, this one is a little tough for me to explain.

I have a runnable jar file that contains a .exe that I'm trying to exec in my program like a command line function.

Usually to execute a .exe in a command line I would do:
C:\"path to .exe" -option etc etc

This would be the same as doing this in java:
Runtime.getRuntime().exec("'path to .exe' -option etc etc");

What if the .exe was in a jar file and my class was using the above command to execute it?

If I try to use:

final String FILEPATH= "\""+getClass().getResource("file.exe").getPath().split("/",2)[1].replace("%20", " ")+"\"";

If I compile outside of the .jar file, I get the correct path. If I run it using the .jar file, I get something like:

.../File_Name.jar!/file.exe which of course doesnt work..

btw, I know the way I did this was all jacked up. Can anyone help me? I'm sure theres a better way. I can try to explain more if I can.

Recommended Answers

All 4 Replies

which of course doesnt work..

So don't do that.

btw, I know the way I did this was all jacked up. Can anyone help me? I'm sure theres a better way. I can try to explain more if I can.

Extract the file before you run it. Look at the JarFile class and specifically the getInputStream(java.util.zip.ZipEntry) will let you get an input stream for a particular entry, which you can then write to an output stream.

Thanks Ezzaral.

I'm a little unsure of how I would extract just that 1 file, but I guess its necessary.

Is there a better way I can get an absolute path to a file without using that junky piece of code up top?

Here is a small function that will extract a single entry from a jar file. The "jarEntry" parameter is simply a string path like "com/myPackage/MyClass.class" that denotes the entry you want to extract

public static void extractFromJar(String jarEntry, File jar, File outputFile) throws IOException{
        JarFile jarFile = new JarFile(jar);
        JarEntry entry = jarFile.getJarEntry(jarEntry);
        if (entry!=null){
            InputStream jarEntryStream = jarFile.getInputStream(entry);
            FileOutputStream outStream = new FileOutputStream(outputFile);
            byte[] buffer = new byte[1024];
            int bytes;
            while ((bytes = jarEntryStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, bytes);
            }
            outStream.close();
            jarEntryStream.close();
            jarFile.close();
        }
    }

As for your path question, you can use getResource() as you did above to search for a resource location in the class path or you can use System.getProperty("user.dir") to obtain the path that the app is currently executing in.

Excellent. Thank you Ezzaral. You've been a great help. I've never used System.getProperty() until now. This will be very useful.

I've also took your function a little further and modified it into an extractResource() function. That way I dont have to worry about keeping track of the .jar file's name or worry about paths & I can also use the same code with or without creating the .jar first since its using a resource instead of a static .jar file that must be there.

/**
 * Extracts the resource with the given name into the destination file.
 * If for some reason the program is unable to write the destination file,
 * an error presents before forcing the application to close.
 * 
 * @param name The name of the resource
 * @param dstFile The destination file where the resource will be extracted to
 * 
 * @return The absolute path of destination file.
 */
public String extractResource(String name, File dstFile) {
	try {
		InputStream resource = getClass().getResourceAsStream(name);
		FileOutputStream outStream = new FileOutputStream(dstFile);
		byte[] buffer = new byte[1024];
		int bytes;
		while ((bytes = resource.read(buffer)) != -1) {
			outStream.write(buffer, 0, bytes);
		}
		outStream.close();
		resource.close();
	} catch (IOException e) {
		JOptionPane.showMessageDialog(this, "Unable to write to: "+	dstFile.getAbsolutePath(), 
				"ERROR: Permissions", JOptionPane.ERROR_MESSAGE);
		System.exit(-1);
	}

	System.out.println("Successfully extracted "+dstFile.getAbsolutePath());
	return dstFile.getAbsolutePath();
}

Much appreciated!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.