title: Java - Loading dlls by a relative path and hide them inside a jar
body: <h1>PART 1</h1>
  
  <p>I am developing a Java application that should be release as a jar. This program depends on C++ external libraries called by JNI. To load them, I use the method <code>System.load</code> with an absolute path and this works fine.</p>
  
  <p>However, I really want to "hide" them inside the JAR, so I have created a package to collect them. This forces me to load an relative path - the package path. By this approach, I let the user run the JAR in any directory, without being worried about linking the DLLs or bored with a previous installation process.</p>
  
  <p>This throws the expected exception:</p>
  
  <blockquote>
    <p>Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library</p>
  </blockquote>
  
  <p>How can I get this working?</p>
  
  <h1>PART 2</h1>
  
  <p>The approach of copying the DLLs to a folder (explained below) only works when I run it under the eclipse environment. Running an exported JAR, the DLL binaries are well created but loading the JNI one throws the next exception:</p>
  
  <blockquote>
    <p>Exception in thread "main" java.lang.reflect.InvocationTargetException</p>
  
  <pre><code> at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56)
   Caused by: java.lang.UnsatisfiedLinkError: C:\Users\Supertreta\Desktop\nm files\temp\jniBin.dll: Can't find dependent libraries at java.lang.ClassLoader$NativeLibrary.load(Native Method)
  </code></pre>
  </blockquote>
  
  <p>I run this loading method:</p>
  
  <pre><code>public static void loadBinaries(){
          String os = System.getProperty("os.name").toLowerCase();
  
          if(os.indexOf("win") &gt;= 0){
              ArrayList&lt;String&gt; bins = new ArrayList&lt;String&gt;(){{
                  add("/nm/metadata/bin/dependence1.dll");
                  add("/nm/metadata/bin/dependence2.dll");
                  add("/nm/metadata/bin/dependence3.dll");
                  add("/nm/metadata/bin/dependence4.dll");
                  add("/nm/metadata/bin/jniBin.dll");
              }};
  
              File f = null;
              for(String bin : bins){
                  InputStream in = FileManager.class.getResourceAsStream(bin);
                  byte[] buffer = new byte[1024];
                  int read = -1;
                  try {
                      String[] temp = bin.split("/");
                      f = new File(TEMP_FOLDER, temp[temp.length-1]);     
                      FileOutputStream fos = new FileOutputStream(f);
  
                      while((read = in.read(buffer)) != -1) {
                          fos.write(buffer, 0, read);
                      }
                      fos.close();
                      in.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
  
              System.load(f.getAbsolutePath());
          }
      }
  </code></pre>
  
  <p>I think this could be an access privileges issue, but don't know how to solve it. What do you think?</p>