tags:

views:

1790

answers:

5

Hi,

I am executing an exe through my java program. the path is hardcoded in java.

I have packaged my the exe in the jar.

But am stuck as i have the path name hardcoded in the java file. so am not able to execute my jar as a stand alone program.

Any hints for packaging such jar i.e having an exe inside and able to run it as a stand alone program?

Thanks, Krisp

+7  A: 

The operating system doesn't care or know about .jar file, so you'll have to unpack the .exe file to some temporary location before you execute it.

Joachim Sauer
A: 

You could write a simple java program to launch the exe using Runtime.exec(). You could then set the "Main-Class" attribute of the jar to be that launcher class. Users could then run your jar and it would run the exe.

Kevin
In this case i will require to hard code the exe path in java code. I want to make it portable.
krisp
@Krisp. Not true. You can use Class/ClassLoader.getResource() to find a relative path within the jar
Kevin
thanks ..this seem's some hopes..will try this out and let u know.
krisp
This can't work - Runtime.exec() tells the OS to execute something, and the OS can't execute something inside a JAR file.
Michael Borgwardt
@Michael He can extract the executable to a temporary directory and run it from there.
Kevin
+1  A: 

Oddly enough I have to write similar code this morning... thanks for pushing me to get that done :-)

This will extract the .exe to a local file on the local disk. The file will be deleted when the Java program exists.

Edit: Whoops, forgot actually copy the file...

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

public class Main
{
    public static void main(final String[] args)
        throws URISyntaxException,
               ZipException,
               IOException
    {
        final URI uri;
        final URI exe;

        uri = getJarURI();
        exe = getFile(uri, "Main.class");
        System.out.println(exe);
    }

    private static URI getJarURI()
        throws URISyntaxException
    {
        final ProtectionDomain domain;
        final CodeSource       source;
        final URL              url;
        final URI              uri;

        domain = Main.class.getProtectionDomain();
        source = domain.getCodeSource();
        url    = source.getLocation();
        uri    = url.toURI();

        return (uri);
    }

    private static URI getFile(final URI    where,
                               final String fileName)
        throws ZipException,
               IOException
    {
        final File location;
        final URI  fileURI;

        location = new File(where);

        // not in a JAR, just return the path on disk
        if(location.isDirectory())
        {
            fileURI = URI.create(where.toString() + fileName);
        }
        else
        {
            final ZipFile zipFile;

            zipFile = new ZipFile(location);

            try
            {
                fileURI = extract(zipFile, fileName);
            }
            finally
            {
                zipFile.close();
            }
        }

        return (fileURI);
    }

    private static URI extract(final ZipFile zipFile,
                               final String  fileName)
        throws IOException
    {
        final File         tempFile;
        final ZipEntry     entry;
        final InputStream  zipStream;
        OutputStream       fileStream;

        tempFile = File.createTempFile(fileName, Long.toString(System.currentTimeMillis()));
        tempFile.deleteOnExit();
        entry    = zipFile.getEntry(fileName);

        if(entry == null)
        {
            throw new FileNotFoundException("cannot find file: " + fileName + " in archive: " + zipFile.getName());
        }

        zipStream  = zipFile.getInputStream(entry);
        fileStream = null;

        try
        {
            final byte[] buf;
            int          i;

            fileStream = new FileOutputStream(tempFile);
            buf        = new byte[1024];
            i          = 0;

            while((i = zipStream.read(buf)) != -1)
            {
                fileStream.write(buf, 0, i);
            }
        }
        finally
        {
            close(zipStream);
            close(fileStream);
        }

        return (tempFile.toURI());
    }

    private static void close(final Closeable stream)
    {
        if(stream != null)
        {
            try
            {
                stream.close();
            }
            catch(final IOException ex)
            {
                ex.printStackTrace();
            }
        }
    }
}
TofuBeer
Dont forget to set the executable flag, otherwise your code works on Windows only.
Adrian
A: 

Tofu what if I wanted to add couple more files inside? can you just easily copy and paste? can someone help me compile this. I'm a java noob. I know C++ and VB.net.

-Thanks in Advance

A: 

Hi there guys and girls. I have a very similar thing happening in my applet jar. It copies the lame encoder binary (so I can convert a recorded wav to mp3 before upload) to a temporary location outside the jar and then tries to execute.

I'm using the MacOSX system so I run the chmod +x /tmp/ command to make it executable before running. Problem is I get a..

java.io.IOException: /tmp/TEMP_28966lamemac: cannot execute at java.lang.UNIXProcess.forkAndExec(Native Method) at java.lang.UNIXProcess.(UNIXProcess.java:52) at java.lang.ProcessImpl.start(ProcessImpl.java:91) at java.lang.ProcessBuilder.start(ProcessBuilder.java:451) at java.lang.Runtime.exec(Runtime.java:591) at java.lang.Runtime.exec(Runtime.java:429)

..exception.

The weird thing is that fine if I run the applet without packaging inside a jar...but it doesn't work when packaged up.

I even browsed to the lame binary that had been successfully copied outside the jar and ran it manually through terminal (/tmp/TEMP_28978lamemac) and it worked meaning the chmod command worked. Why can I copy the binary, change permissions successfully, but not run it from my jar?

Thanks for your time,

Mitch