外部罐子中的资源加载不起作用

时间:2014-07-30 22:17:15

标签: java eclipse jar lwjgl slick2d

我正在使用LWJGL和Slick2d制作游戏,并且自然会将游戏资产导出到我的jar中使用。但是,它们无法从我使用jarsplice创建的runnable .jar中加载,但在与.jar文件位于同一文件夹中时运行。我试图使用.getSystemResource()和.getSystemResourceAsStream()来加载Eclipse中的源代码中的文件来解决这个问题,但它不起作用。我花了几个小时搜索stackoverflow,gamedev.net,lwjgl论坛和slick2d论坛,用于从Eclipse导出的jar中加载资源,但无济于事。这是我经历的过程:

1)我配置了我的构建路径 - 包含所有内容,没有任何内容被排除在外。

2)正确添加所有库;

3)选择所有内容进行订购和导出。

4)我导出为一般(不可运行).jar,取消选择那些未被我的代码引用的文件夹和包。包含我的音频,图像和着色器的文件夹已正确标记为导出。

http://imgur.com/ldHuC1x.jpg

5)我打开.jar文件,所有内容都应该在里面。此时,清单文件为空。

6)我使用jarsplice创建一个胖.jar,首先添加.jar文件;

7)接下来我添加了lwjgl;

所需的所有原生代码

8)最后我使用完整的包路径进入我的主类。

9)当我创建.jar并查看内部时,所有内容都应包含在其中。

http://imgur.com/o9qX3iW.jpg

另外,清单文件现在已正确填写:

Manifest-Version: 1.0
Launcher-VM-Args: 
Launcher-Main-Class: com.fafnir.gestalt.Bootstrap
Main-Class: org.ninjacave.jarsplice.JarSpliceLauncher

10)运行.jar后使用' java -jar FatRunnable.jar'我收到错误,所以我创建了一个.bat文件来运行它并将输出记录在一个文本文件中:

java -jar FatRunnable.jar %* > log.txt
PAUSE

11)我检查文本文件并看到以下内容:

Wed Jul 30 17:42:11 EDT 2014 INFO:Initialising sounds..
[LWJGL] getPathFromClassLoader: searching for: OpenAL32
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] getPathFromClassLoader: searching for: lwjgl
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] getPathFromClassLoader: searching for: lwjgl
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] Found 6 OpenAL paths
[LWJGL] Testing 'C:\Users\MOTHAF~1\AppData\Local\Temp\\natives-1942957663\OpenAL64.dll'
[LWJGL] Found OpenAL at 'C:\Users\MOTHAF~1\AppData\Local\Temp\\natives-1942957663\OpenAL64.dll'
[LWJGL] MemoryUtil Accessor: AccessorUnsafe
Wed Jul 30 17:42:11 EDT 2014 INFO:- Sound works
Wed Jul 30 17:42:11 EDT 2014 INFO:- 64 OpenAL source available
Wed Jul 30 17:42:11 EDT 2014 INFO:- Sounds source generated
[LWJGL] Initial mode: 1600 x 900 x 32 @60Hz
[LWJGL] Found 32 displaymodes
[LWJGL] Removed 20 duplicate displaymodes
Detected display modes:
800x600x32 60Hz
1600x900x16 60Hz
640x480x16 60Hz
1024x768x16 60Hz
1280x720x32 60Hz
1280x800x16 60Hz
800x600x16 60Hz
1600x900x32 60Hz
640x480x32 60Hz
1024x768x32 60Hz
1280x720x16 60Hz
1280x800x32 60Hz
[LWJGL] GL_EXT_direct_state_access was reported as available but an entry point is missing
OpenGL version: 3.2.9712 Core Profile Forward-Compatible Context
Could not read file.
java.io.FileNotFoundException: glsl\textured.vs (The system cannot find the path specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:131)
    at java.io.FileInputStream.<init>(FileInputStream.java:87)
    at java.io.FileReader.<init>(FileReader.java:58)
    at com.fafnir.gestalt.quads.QuadUpdateVBO.loadShader(QuadUpdateVBO.java:180)
    at com.fafnir.gestalt.quads.QuadUpdateVBO.setupShaders(QuadUpdateVBO.java:146)
    at com.fafnir.gestalt.quads.QuadUpdateVBO.<init>(QuadUpdateVBO.java:49)
    at com.fafnir.gestalt.Bootstrap.setupArtists(Bootstrap.java:167)
    at com.fafnir.gestalt.Bootstrap.<init>(Bootstrap.java:72)
    at com.fafnir.gestalt.Bootstrap.main(Bootstrap.java:38)
AL lib: (EE) alc_cleanup: 1 device not closed
Could not locate symbol glEnableClientStateiEXT
Could not locate symbol glDisableClientStateiEXT
Could not locate symbol glGetFloati_vEXT
Could not locate symbol glGetDoublei_vEXT
Could not locate symbol glGetPointeri_vEXT
Could not locate symbol glNamedCopyBufferSubDataEXT
Could not locate symbol glVertexArrayIndexOffsetEXT
Could not locate symbol glVertexArrayVertexAttribOffsetEXT
Could not locate symbol glVertexArrayVertexAttribIOffsetEXT
Could not locate symbol glEnableVertexArrayEXT
Could not locate symbol glDisableVertexArrayEXT
Could not locate symbol glEnableVertexArrayAttribEXT
Could not locate symbol glDisableVertexArrayAttribEXT
Could not locate symbol glGetVertexArrayIntegervEXT
Could not locate symbol glGetVertexArrayPointervEXT
Could not locate symbol glGetVertexArrayIntegeri_vEXT
Could not locate symbol glGetVertexArrayPointeri_vEXT
Could not locate symbol glMapNamedBufferRangeEXT
Could not locate symbol glFlushMappedNamedBufferRangeEXT

12)看起来,尽管着色器位于.jar文件中,但它找不到位于&#39; glsl&#39;中的着色器。夹。从我收集的内容来看,这是因为它们不是单独的文件,而是位于.jar中,必须使用不同的代码进行访问。

通过将文件路径连同GL20值传递给我的loadShader(String fileName,int type)方法来加载着色器:

// Load the vertex shader
vsId = loadShader("glsl/textured.vs", GL20.GL_VERTEX_SHADER);

// Load the fragment shader
fsId = loadShader("glsl/textured.fs", GL20.GL_FRAGMENT_SHADER);

13)在eclipse中工作的loadShader方法,但不是.jar的方法如下:

public static int loadShader(String fileName, int type) {
    final StringBuilder shaderSource = new StringBuilder();
    int shaderID = 0;

    try {
        final BufferedReader reader = new BufferedReader(new FileReader(fileName));
        String line;
        while ((line = reader.readLine()) != null) {
            shaderSource.append(line).append("\n");
        }
        reader.close();
    } catch (final IOException e) {
        System.err.println("Could not read file.");
        e.printStackTrace();
        System.exit(-1);
    }

    shaderID = GL20.glCreateShader(type);
    GL20.glShaderSource(shaderID, shaderSource);
    GL20.glCompileShader(shaderID);

    if (GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
        // Check for any OpenGL errors
        OpenGLHelper.exitOnGLError("Error in quads.QuadUpdateVBO.loadShader()");
    }

    return shaderID;
}
14)我试图改变它以使用ClassLoader,以便它可以使用.jar中包含的资源,但我甚至无法让它在eclipse中工作。这是我的新方法:

public static int loadShader(String fileName, int type) {
    final StringBuilder shaderSource = new StringBuilder();
    int shaderID = 0;

    try (InputStream shaderStream = QuadUpdateVBO.class.getResourceAsStream(fileName);
            BufferedReader reader = new BufferedReader(new InputStreamReader(shaderStream))) {
        String line;
        while ((line = reader.readLine()) != null) {
            shaderSource.append(line).append("\n");
        }
    } catch (final IOException e) {
        System.err.println("Could not read file.");
        e.printStackTrace();
        System.exit(-1);
    }

    shaderID = GL20.glCreateShader(type);
    GL20.glShaderSource(shaderID, shaderSource);
    GL20.glCompileShader(shaderID);

    if (GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
        // Check for any OpenGL errors
        OpenGLHelper.exitOnGLError("Error in quads.QuadUpdateVBO.loadShader()");
    }

    return shaderID;
}

以下是运行我的Bootstrap类时我的Eclipse控制台的输出:

Wed Jul 30 17:58:02 EDT 2014 INFO:Initialising sounds..
[LWJGL] getPathFromClassLoader: searching for: OpenAL32
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] getPathFromClassLoader: searching for: lwjgl
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] getPathFromClassLoader: searching for: lwjgl
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException:     java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] Found 14 OpenAL paths
[LWJGL] Testing 'C:\Program Files\eclipse\external jars\LWJGL     2.9.2\native\windows\OpenAL64.dll'
[LWJGL] Found OpenAL at 'C:\Program Files\eclipse\external jars\LWJGL     2.9.2\native\windows\OpenAL64.dll'
[LWJGL] MemoryUtil Accessor: AccessorUnsafe
Wed Jul 30 17:58:03 EDT 2014 INFO:- Sound works
Wed Jul 30 17:58:03 EDT 2014 INFO:- 64 OpenAL source available
Wed Jul 30 17:58:03 EDT 2014 INFO:- Sounds source generated
[LWJGL] Initial mode: 1600 x 900 x 32 @60Hz
[LWJGL] Found 32 displaymodes
[LWJGL] Removed 20 duplicate displaymodes
Detected display modes:
800x600x32 60Hz
1600x900x16 60Hz
640x480x16 60Hz
1024x768x16 60Hz
1280x720x32 60Hz
1280x800x16 60Hz
800x600x16 60Hz
1600x900x32 60Hz
640x480x32 60Hz
1024x768x32 60Hz
1280x720x16 60Hz
1280x800x32 60Hz
[LWJGL] GL_EXT_direct_state_access was reported as available but an entry point is     missing
OpenGL version: 3.2.9712 Core Profile Forward-Compatible Context
Exception in thread "main" java.lang.NullPointerException
    at java.io.Reader.<init>(Unknown Source)
    at java.io.InputStreamReader.<init>(Unknown Source)
    at com.fafnir.gestalt.quads.QuadUpdateVBO.loadShader(QuadUpdateVBO.java:194)
    at com.fafnir.gestalt.quads.QuadUpdateVBO.setupShaders(QuadUpdateVBO.java:147)
    at com.fafnir.gestalt.quads.QuadUpdateVBO.<init>(QuadUpdateVBO.java:50)
    at com.fafnir.gestalt.Bootstrap.setupArtists(Bootstrap.java:167)
    at com.fafnir.gestalt.Bootstrap.<init>(Bootstrap.java:72)
    at com.fafnir.gestalt.Bootstrap.main(Bootstrap.java:38)
AL lib: (EE) alc_cleanup: 1 device not closed
Could not locate symbol glEnableClientStateiEXT
Could not locate symbol glDisableClientStateiEXT
Could not locate symbol glGetFloati_vEXT
Could not locate symbol glGetDoublei_vEXT
Could not locate symbol glGetPointeri_vEXT
Could not locate symbol glNamedCopyBufferSubDataEXT
Could not locate symbol glVertexArrayIndexOffsetEXT
Could not locate symbol glVertexArrayVertexAttribOffsetEXT
Could not locate symbol glVertexArrayVertexAttribIOffsetEXT
Could not locate symbol glEnableVertexArrayEXT
Could not locate symbol glDisableVertexArrayEXT
Could not locate symbol glEnableVertexArrayAttribEXT
Could not locate symbol glDisableVertexArrayAttribEXT
Could not locate symbol glGetVertexArrayIntegervEXT
Could not locate symbol glGetVertexArrayPointervEXT
Could not locate symbol glGetVertexArrayIntegeri_vEXT
Could not locate symbol glGetVertexArrayPointeri_vEXT
Could not locate symbol glMapNamedBufferRangeEXT
Could not locate symbol glFlushMappedNamedBufferRangeEXT

1 个答案:

答案 0 :(得分:0)

想出一个可靠的方法来回答我自己的问题 - 通过创建一个名为'ResourceHandler'的新类我设置了几个方法来将Strings作为参数,以及一个布尔值(以指示它是否被加载以.getSystemResourceAsStream(或不)的方式,并吐出BufferedReaders,InputStreams或Audio对象,它们在Eclipse中工作,并使用jarsplice打包在Fat .jar中。这是该类的代码:

package com.fafnir.gestalt.helpers;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;

import org.newdawn.slick.openal.Audio;
import org.newdawn.slick.openal.AudioLoader;
import org.newdawn.slick.util.ResourceLoader;

public class ResourceHandler {

/**
 * Returns a buffered reader of the input file from a (non/)streaming resource
 * 
 * @param filePath
 * @param streaming
 * @return
 */
public static BufferedReader loadIntoBufferedReader(String filePath, boolean streaming) {
    BufferedReader reader = null;
    if (streaming) {
        InputStream stream = ResourceLoader.getResourceAsStream(filePath);
        InputStreamReader isr = new InputStreamReader(stream);
        reader = new BufferedReader(isr);
    } else {
        URL url = ResourceLoader.getResource(filePath);

        try (FileReader freader = new FileReader(url.toURI().toString())) {
            reader = new BufferedReader(freader);
        } catch (FileNotFoundException fnfe) {
            System.err.println("File " + filePath + " does not exist!");
            fnfe.printStackTrace();
            System.exit(1);
        } catch (URISyntaxException urise) {
            System.err.println("Bad URI syntax for " + filePath + "!");
            urise.printStackTrace();
            System.exit(1);
        } catch (IOException ioe) {
            System.err.println("File " + filePath + " couldn't be read/written to!");
            ioe.printStackTrace();
            System.exit(1);
        }
    }

    return reader;
}

/**
 * Returns an InputStream of the input file
 * 
 * @param filePath
 * @return
 */
public static InputStream loadIntoInputStream(String filePath) {
    InputStream stream = ResourceLoader.getResourceAsStream(filePath);
    return stream;
}

/**
 * Returns an Audio object of the input file as a stream
 * 
 * @param type
 * @param filePath
 * @return
 */
public static Audio loadIntoAudio(String type, String filePath, boolean streaming) {
    Audio audio = null;
    try {
        if (streaming) {
            audio = AudioLoader.getStreamingAudio(type, ResourceLoader.getResource(filePath));
        } else {
            audio = AudioLoader.getAudio(type, ResourceLoader.getResourceAsStream(filePath));
        }
    } catch (final IOException ioe) {
        System.err.println("File " + filePath + " couldn't be read/written to!");
        ioe.printStackTrace();
        System.exit(1);
    }
    return audio;
}

}