2
\$\begingroup\$

Okay, so I know I need to set the path to the native files. I can do this in Eclipse, by going to the VM arguments and using -Djava.library.path=, but when I export, it says that the VM arguments aren't kept after exporting, but it can be set in the console while running it. I am running Mac OS X. How do I set that using Terminal?

\$\endgroup\$
2
\$\begingroup\$

It should be exactly the same, just provide -Djava.library.path="your_path" to java when you run it:

java -Djava.library.path="your_path" -classpath "your_classpath" your.main.Class
\$\endgroup\$
  • \$\begingroup\$ Wouldja look at that. If only my 30 minutes of Google searching could have just said that. Thanks! \$\endgroup\$ – Brandon oubiub Jun 24 '11 at 2:55
0
\$\begingroup\$

I just wrote a nifty way to solve this problem, without needing to define the library beforehand. Which is more useful when you actually deploy your game. Basically it goes like this:

  1. Detect OS and architecture
  2. Copy LWJGL native binaries from inside your .jar file to game directory
  3. Dynamically set library path for Java to the natives folder in your game directory
  4. Continue with the rest of your game loading

This needs to happen first thing. So at the beginning of your main function goes:

loadNatives(getPlatform());

Then you have your getPlatform() function (step 1 from above), you can get the OS details like so:

String OS_Arch = System.getProperty("os.arch").toLowerCase();
String OS_Name = System.getProperty("os.name").toLowerCase();

Use those to return an enum that defines your OS and architecture, i.e. Win_X86.

Then you load your natives that are packaged in your .jar file (step 2 from above). Depending on the OS and architecture you'll load certain files from the LWJGL native binaries. For example Win_X86 would be something like:

String path = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
copyFileFromJar("/assets/native/windows/jinput-raw.dll",
  path + "/native/jinput-raw.dll");
copyFileFromJar("/assets/native/windows/jinput-dx8.dll",
  path + "/native/jinput-dx8.dll");
copyFileFromJar("/assets/native/windows/lwjgl.dll",
  path + "/native/lwjgl64.dll");
copyFileFromJar("/assets/native/windows/OpenAL32.dll",
  path + "/native/OpenAL32.dll");

Where copyFileFromJar() just makes an input stream and an output stream, then streams until it can stream no more. The input stream is from the native file in your .jar and the output is the destination file (which probably needs to be created first!)

Finally, tell Java about this new library resource (Step 3 from above):

System.setProperty("java.library.path", path + "native/");
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
\$\endgroup\$
0
\$\begingroup\$

Use this class to load Natives from anywhere in your system.

import java.lang.reflect.Field;
import java.util.Arrays;

public class NativeLoader
{
 public static void loadNatives(String nativepath)
 {
     try
     {  

     Field natives=ClassLoader.class.getDeclaredField("sys_paths");

      natives.setAccessible(true);

      String paths[]=(String[])natives.get(null);

      for(int i=0;i<paths.length;i++)
      {
        if(paths[i].equalsIgnoreCase(nativepath))
        {
          return;  
        }    
      }

      String newpaths[]=Arrays.copyOf(paths,paths.length+1);

      newpaths[newpaths.length-1]=nativepath;

      natives.set(null,newpaths); 
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
 }
}

This method should be called as the first method in your main method.

Works in JDK 1.7 and 1.8 so far.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.