Getting natives to work on Mac/Linux if you don't have either.

Hey all, I’m hitting a bit of a snag with something that should be simple. I’ve tried many methods (including jarsplice and similar programs) to get my natives working on Mac and Linux, the problem is, I don’t have a Mac or Linux machine to test my game on. But it seems no matter what I do, I get the “java.lang.UnsatisfiedLinkError: no lwjgl in java.library.path” error from my Mac and Linux users who test the program.

The latest way I’ve tried to force native support (that removes the need for jarsplice or anything like it) is to hack my java.lang.path by launching the game with this method:


package core;
import java.lang.reflect.Field;

public class Launcher {
	public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		System.setProperty("java.library.path", "lib/natives;lib/jars;"+System.getProperty("java.library.path"));
		final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
		sysPathsField.setAccessible(true);
		sysPathsField.set(null, null);
		System.out.println(System.getProperty("java.library.path"));
		Game.launchGame();
	}
	
}

It works great for PCs, I can just export the jar and run it on any PC with Java 1.6+ with no trouble. But I still get the natives error on the other 2 OSes. It should also be noted all my natives are in lib/natives/, they’re not in subfolders.

Normally I figure I can solve this problem myself, but without access to a Mac I can’t exactly troubleshoot the problem, and all the solutions I’ve looked for seem to not be working, where you’d think this should be an easy fix.

I’m not too familiar with Macs since I avoid them, is their file structure different somehow? Is folderYouLaunchedIn/lib/natives not lib/natives/ as the machine sees it on a mac? I have a feeling my problem is something painfully simple, but I’m just not seeing it.

Install linux on an external HDD… That’s what I did.

Have you tried creating an executable that runs “java -Djava.library.path=“yournatives” -jar thegame.jar”? I’m guessing you have though.
Another option is to run a VM of some nix distribution and test on there until you get it. But that doesn’t cover Mac unfortunately.


All that does is solve the problem on windows, where it works anyway. :smiley: The exported builds work like a champ on basically all PCs (as far as I’ve tested anyway), it’s just the Macs and Linux machines that faulter.

EDIT: Sorry, misread your post, I thought you meant a windows executable. Yeah, I had considered that option, but I didn’t want to have to juggle a mac and windows executable (at least not yet).

I may install a Linux disto on one of my PCs to at least get that up and running, but really Mac is my target. Not many people are going to be using my game on a Linux machine anyway.

Remember that on Mac/Linux, when you launch a .jar file by double-clicking, “user.dir” is set to “~/” (user’s home directory).

You need to find out the actual path of the folder containing the jar file, which is where this code comes in handy:


public static String jarDir()
{
	try
	{
		return new File(SomeClass.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent();
	}
	catch(URISyntaxException e)
	{
		e.printStackTrace();
		return null;
	}
}

Finally, if the only natives you need are LWJGL, you can use [icode]System.setProperty(“org.lwjgl.librarypath”, nativesPath);[/icode], which AFAIK, is much cleaner.

Rather than install Linux on a separate partition, you can just monkey around with the basics by installing VirtualBox and then creating a whole virtual Linux in that (I recommend Mint for now). 3D stuff even sort of works.

Cas :slight_smile:

You might be interested in Packr if you haven’t seen that already.

Thanks! It’s being a bit stubborn, but I think thats the direction I need to go. Problem is, all my class files are inside the jar so I have to use an InputStream. But I’ll toy around with that more once I get back to it.

Although I guess if I wanted to be a little hacky, I could have an empty class file external to the jar. :stuck_out_tongue:

ohh, I like the way that sounds. I think I’ll give it a shot.

Okay, so here’s the easiest solution that I’m aware of:

System.setProperty("org.lwjgl.librarypath", Paths.get("WhereYouStoreYourNatives", LWJGLUtil.getPlatformName()).toAbsolutePath().toString());

Of course change ‘WhereYouStoreYourNatives’ to the folder where, well… Where you store your natives. ;D
Keep in mind that this only works if your natives are outside of your JAR, and also the Path class requires Java 7 (although the whole thing can be done just as easily in Java 6 using the File class instead).
If you’re planning on storing the natives inside your JAR you’re going to have to extract them before you can make use of them, which is a bit harder but not utterly complex. :slight_smile:

That code I posted works regardless of whether you’re running it in Eclipse or a jar file.

Or better yet just download an image (with guest additions installed) so you don’t have to waste time with the majority of the installation/set-up process.


http://virtualboximages.com/

hmm? But wouldn’t new File(SomeClass.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() only be able to find Some.Class if it wasn’t in a jar? Since it’s no longer a “file” inside the jar?

Maybe I goofed up somewhere else then. Really annoying troubleshooting an OS you don’t have. :stuck_out_tongue:

That code gives you the directory the jar is in, not anything inside the jar. It works, but it may not be what you need.