Hot questions for Using Lightweight Java Game Library in jar

Question:

I'm developing a game with LWJGL 3.0.0a. Many tutorials out there use the lwjgl_util.jar that contains stuff like Vector2f and GLU for functions like gluUnProject.

In this version though (available on the downloads page) there is no such library contained anymore; it only contains the core lwjgl.jar. Where have these utils gone?


Answer:

LWJGL 3 has the focus on the OpenGL bindings. On the wiki it is stated

The library includes functionality and APIs that simply should never have been added to it. Such functionality belongs either to an engine using LWJGL, or to another library layered on top of LWJGL. This includes the util package (vecmath, mapped objects, image/sound file readers, etc) and anything to do with applets.

So essentially this means that, at least for the moment, there will not be any Util package in the core library.

However, there are plans of including one when the other core features (OpenGL ES bindings, Vulkan bindings etc.) have been implemented.

From the roadmap:

  • [.x]: May be postponed to a point release after 3.0.

[...]

[.x] Official utility library.

Even though the focus for LWJGL 3 is to only include the very lightweight, lower-level functionality in the core library, ease-of-use and appeal to novice programmers is also important. The current plan is to start a sibling project that will create an official utility library for LWJGL 3. It will include all non-essential functionality, optional features and helper/convenience utilities. It may also include an API that matches LWJGL 2 for easy porting of existing code. Engine-level functionality, like vecmath and fixed-function simulation, may or may not be included, depending on the amount of support the project receives. Another option is the creation of "profile-based" OpenGL classes, e.g. a GLCore class that includes only the core profile functionality from GL11 up to GL31.

[...]

Removed Features
The util package.

Some of the old functionality might be added to the utility library.

There was also an unofficial utility project started on the forum, the Java OpenGL Math Library (JOML) (Github page), but it is unclear whether it will be continued.

EDIT: As of June 2015, JOML is a recommendation from the LWJGL team: blog entry.

EDIT: As of June 2015, LWJGL has the STB library included. This provides useful utility functions for image and font loading.

Question:


Answer:

I managed to build my jar with a terminal. Everything I will explain works in a single folder, no subfolder for packages etc.. (for simplicity)

You will need a minimal ZIP bundle from here, including the natives corresponding to the OS(s) you want to distribute for.

  • Compile with javac -cp ".;./lwjgl.jar;./lwjgl-opengl.jar;./lwjgl-glfw.jar" Main.java (replace ; by : if you are on unix system)

  • Create a manifest file myManifest.txt containing:

Manifest-Version: 1.0
Class-Path: ./lwjgl.jar ./lwjgl-glfw.jar ./lwjgl-opengl.jar ./lwjgl-natives-windows.jar
Main-Class: Main

Do not forget the blank line at the end.

  • Jar it with jar -cvfm MyJar.jar .\myManifest.txt .\Main.class

You can now run your jar by double clicking it, you will need all .jar files in this folder, .java, .class and manifest files can be removed.

Question:

I am following along with a tutorial book on LWJGL3 and I tried to make my own image loading code (The book code does not use the STB library) and it works perfectly fine when the project is run normally (IntelliJ IDE, run directly from the build folder), It loads the image from into the ByteBuffer and stbi_load_from_memory works fine, but as soon as it is compiled and put in a jar file it just stops working, Even tho the image was successfully loaded into the ByteBuffer, as if the stbi_load_from_memory function just returns null if it's in a Jar.

The code:

public static ByteBuffer loadImage(String fileName, IntBuffer w, 
    IntBuffer h, IntBuffer comp) throws Exception
    {
        ByteBuffer image;
        //the class name is Utils
        InputStream imageFile = 
        Utils.class.getResourceAsStream(fileName); 

        //The image data gets put into the byte array no matter if
        //its a jar or not
        byte[] imageData = new byte[imageFile.available()];
        imageFile.read(imageData);
        ByteBuffer imageBuffer = 
        BufferUtils.createByteBuffer(imageData.length);
        imageBuffer.put(imageData);
        imageBuffer.flip();
        //imageBuffer is the right size and has the right contents            

        //This is where everything fails if its in a jar,
        //image is set to null and the Exception is thrown
        image = stbi_load_from_memory(imageBuffer, w, h, comp, 0);

        if(image == null)
        {
            throw new Exception("Failed to load image: " + fileName);
        }

        return image;
    }

It can't be a misspelled file name or recourse path, because it loads the data into the array properly no matter if it's a jar or not.

Additional Information:

  • Java version: 1.8.0_131 64bit

  • Processor architecture: amd64

  • IDE version (if needed for some reason): IntelliJ 2017.1.4 Ultimate

  • OS: Ubuntu 16.04 LTS 64 bit

  • Kernel: Linux 4.8.0-58-generic amd64

  • LWJGL version: 3.1.2

  • The project is made in Gradle 3.3

  • if required i will upload and post the link of the entire source code


Answer:

The problem is probably in your imageFile.available(). The available method of InputStream is not a good way to get the size of the stream; in fact you can't get the size of the stream, you have to read it until it ends.

What you want to do is convert your InputStream to a byte array. Look here how to do that: link. The rest of the code should be OK. Note that you need a direct ByteBuffer, so wrapping the byte array will not work, but you are already using the correct method (BufferUtils.createByteBuffer).

In case you still have problems, look at this example from LWJGL: https://github.com/LWJGL/lwjgl3/blob/master/modules/samples/src/test/java/org/lwjgl/demo/stb/Image.java

Question:

I am working on a LWJGL game engine. I want to export the engine as a JAR file that can be utilized in the build path of other projects. I tried using JarSplice to pack in all of the natives, but I am still getting an error when I try to use the engine packed in a jar in a different project.

When I export the engine as a JAR, move it to the build path of another project, and try to run, I am getting an UnsatisfiedLinkError when the JAR engine tries to create an OpenAL instance with AL.create(). From what I'm reading, this is an error with the natives, though I could be wrong in this instance.

How can I export my engine as a jar so it can be used in other projects?


Answer:

With LWJGL 2.x the user of your engine will always have to manually add the natives to the game's native path. They will not get extracted automagically from jar files. The current LWJGL 3 on the other hand provides such functionality and allows you to distribute your engine together with the LWJGL dependency as a jar file. It does this by searching the classpath for the native files and extracting them to a temporary folder and loading them there.

Question:

I'm using LWJGL and Slick-Util. My texture loading works fine in Eclipse, but when I export it to a .jar, it gives java.lang.RuntimeException: Resource not found: res/test/texture.png

This is my texture loading code:

public int loadTexture(String file) {
    Texture tex = null;
    try {
        tex = TextureLoader.getTexture("PNG", new FileInputStream("res/" + file + ".png"));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    int texID = tex.getTextureID();
    textures.add(texID);
    return texID;
}

Answer:

You probably do not run the application from the right directory. For your code to work, you need to start the program in a directory containing the res folder.

Alternatively you can use

...
try {
    tex = TextureLoader.getTexture("PNG", this.getClass().getResourceAsStream("/res/" + file + ".png");
} catch (FileNotFoundException e) {
     ...
}

But in this case res folder needs to be added to classpath:

java -cp .;path/to/res;some.jar your.main.Class

Question:

This is related to (Attach the Source in Eclipse of a jar)

I'm trying to use the LWJGL libraries (specifically org.lwjgl.opengl.jar).

The problem is that the import (import org.lwjgl.opengl.Display) will not resolve properly:

the import org cannot be resolved

. On trying to open the classes in org.jwlg.opengl under "Referenced Libraries", I find:

Source not found

The source attachment does not contain the source for the file XXX

I added the opengl.jar by doing this:

Right click on the project->BuildPath->Configure Build Path->Libraries->Add External Jars

Here is everything I have tried to fix:

  • Removed the reference and re-added it

  • Cleaned the project (Project > clean). (didn't work)

  • I tried using Java Source Attacher (https://marketplace.eclipse.org/content/java-source-attacher) but it isn't compatible with my version of Eclipse

  • Imported the org.lwjgl.opengl.jar file as a project and attaching it to the reference as the source, but it hasn't worked.

I have been downloading the library from https://www.lwjgl.org/customize

This is a possible solution but I don't understand the answer at all, could someone explain? LWJGL jar not accesable


Answer:

org.lwjgl.opengl.Display is from LWJGL 2, you downloaded LWJGL 3. See the guide: https://www.lwjgl.org/guide for its replacement.

Question:

So I'm trying to teach myself LWJGl for fun, so I make the project file, put the things into the pom.xml file, and then I get this error:

Missing artifact org.lwjgl:lwjgl-platform:jar:natives-windows:${lwjgl.version}

This is my pom.xml file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>learninglwjgl</groupId>
  <artifactId>learninglwjgl</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>learninglwjgl</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
     <dependency>
            <groupId>org.lwjgl</groupId>
            <artifactId>lwjgl-platform</artifactId>
            <version>${lwjgl.version}</version>
            <classifier>${native.target}</classifier>
        </dependency>
  </dependencies>

   <profiles>
        <profile>
            <id>windows-profile</id>
            <activation>
                <os>
                    <family>Windows</family>
                </os>
            </activation>
            <properties>
                <native.target>natives-windows</native.target>
            </properties>                
        </profile>
        <profile>
            <id>linux-profile</id>
            <activation>
                <os>
                    <family>Linux</family>
                </os>
            </activation>
            <properties>
                <native.target>natives-linux</native.target>
            </properties>                
        </profile>
        <profile>
            <id>OSX-profile</id>
            <activation>
                <os>
                    <family>mac</family>
                </os>
            </activation>
            <properties>
                <native.target>natives-osx</native.target>
            </properties>
        </profile>
    </profiles>

</project>

Any help would be appreciated, thanks :)


Answer:

You should define a property for ${lwjgl.version}. As you can see at Maven Central, the only version of this artifact is 3.0.0 and you must explicitly define it. Please replace your <properties> tag with the following:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <lwjgl.version>3.0.0</lwjgl.version>
</properties>

Also, you might want to get use of the offical LWJGL page describing setting up Maven project, as I am not sure if your pom.xml includes all necessary dependencies.

Question:

I'm using LWJGL and OpenGL. My program works in Eclipse, but when I export it I get a java.lang.UnsatisfiedLinkError: no lwjgl in java.library.path.

Can someone help me export the jar with the lwjgl files?


Answer:

If you looked at LWJGL wiki you would know that you need to define where native libraries are located. In Eclipse you can configure them for every individual JAR file, so it is easy to forget that it is necessary to pass additional arg when running from command line

-Djava.library.path=<lwjgl dir>\native\windows

For instance:

java -cp .;res;jar\lwjgl.jar;jar\lwjgl_test.jar;jar\lwjgl_util.jar;jar\jinput.jar;c:\some-other.jar -Djava.library.path=native\windows org.lwjgl.test.WindowCreationTest

This example is taken from the wiki page.

However, if you wanted to generate a runnable JAR with these libraries then more work is needed. Look here for some guidance.

Question:

This should be a pretty simple question. I am trying to us LWJGL and I watched a tutoiral on how to get started but the import statements and all lwjgl code is getting error messages. The file is below. What am I doing wrong? I added the jar in properties but it is still not working.

https://www.mediafire.com/?vbckyjkr6di8dlk


Answer:

LWJGL uses its own variables for the path to the native libraries (If they are not found you will get a "no LWJGL in path"-error):

System.setProperty("org.lwjgl.librarypath", new File("pathToNatives").getAbsolutePath());

If you kept the file structure from the LWJGL package you can use something like this:

switch(LWJGLUtil.getPlatform())
{
    case LWJGLUtil.PLATFORM_WINDOWS:
    {
        JGLLib = new File("./native/windows/");
    }
    break;

    case LWJGLUtil.PLATFORM_LINUX:
    {
        JGLLib = new File("./native/linux/");
    }
    break;

    case LWJGLUtil.PLATFORM_MACOSX:
    {
        JGLLib = new File("./native/macosx/");
    }
    break;
}

System.setProperty("org.lwjgl.librarypath", JGLLib.getAbsolutePath());

Question:

After exporting my game to jar it does not work. Exception in thread "main" java.lang.UnsatisfiedLinkError: no jinput-dx8_64 in java.library.path

I read that I have to put the files anywhere in my computer and add the .dll files path to java.libraty.path, but, will it work if I try the game in another computer?

Tanks :D


Answer:

If you are working on windows, just add the path of the dll file along with the java path in environment variable. For example. If your dll file is present in jdk/jre/bin,path=C:\Program Files\Java\jdk1.8.0_25\jre\bin. Just try this one. Once worked for me.