5

I have a .jar that has two .dll files that it is dependent on. I would like to know if there is any way for me to copy these files from within the .jar to a users temp folder at runtime. here is the current code that I have (edited to just one .dll load to reduce question size):

public String tempDir = System.getProperty("java.io.tmpdir");
public String workingDir = dllInstall.class.getProtectionDomain().getCodeSource().getLocation().getPath();

public boolean installDLL() throws UnsupportedEncodingException {

try {
             String decodedPath = URLDecoder.decode(workingDir, "UTF-8");
             InputStream fileInStream = null;
             OutputStream fileOutStream = null;

             File fileIn = new File(decodedPath + "\\loadAtRuntime.dll");
             File fileOut = new File(tempDir + "loadAtRuntime.dll");

             fileInStream = new FileInputStream(fileIn);
             fileOutStream = new FileOutputStream(fileOut);

             byte[] bufferJNI = new byte[8192000013370000];
             int lengthFileIn;

             while ((lengthFileIn = fileInStream.read(bufferJNI)) > 0) {
                fileOutStream.write(bufferJNI, 0, lengthFileIn);
             }

            //close all steams
        } catch (IOException e) {
      e.printStackTrace();
             return false;
        } catch (UnsupportedEncodingException e) {
             System.out.println(e);
              return false;
        }

My main problem is getting the .dll files out of the jar at runtime. Any way to retrieve the path from within the .jar would be helpful.

Thanks in advance.

DeanMWake
  • 893
  • 3
  • 19
  • 38

3 Answers3

8

Since your dlls are bundeled inside your jar file you could just try to acasses them as resources using ClassLoader#getResourceAsStream and write them as binary files any where you want on the hard drive.

Here is some sample code:

InputStream ddlStream = <SomeClassInsideTheSameJar>.class
    .getClassLoader().getResourceAsStream("some/pack/age/somelib.dll");

try (FileOutputStream fos = new FileOutputStream("somelib.dll");){
    byte[] buf = new byte[2048];
    int r;
    while(-1 != (r = ddlStream.read(buf))) {
        fos.write(buf, 0, r);
    }
}

The code above will extract the dll located in the package some.pack.age to the current working directory.

A4L
  • 17,353
  • 6
  • 49
  • 70
0

Use myClass.getClassLoader().getResourceAsStream("loadAtRuntime.dll"); and you will be able to find and copy DLLs in the JAR. You should pick a class which will also be in the same JAR.

spongebob
  • 8,370
  • 15
  • 50
  • 83
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

Use a class loader that is able to locate resources in this JAR file. Either you can use the class loader of a class as Peter Lawrey suggested, or you can also create a URLClassLoader with the URL to that JAR.

Once you have that class loader you can retrieve a byte input stream with ClassLoader.getResourceAsStream. On the other hand you just create a FileOutputStream for the file you want to create.

The last step then is to copy all bytes from the input stream to the output stream, as you already did in your code example.

Seelenvirtuose
  • 20,273
  • 6
  • 37
  • 66