2015-08-14 2 views
1

Я работаю над движком 3D-игр с Java, OpenGL/LWJGL и Slick-Utils, и я не могу пройти мимо этой ошибки (исключение Null Pointer) в программе ,JAR Невозможно загрузить текстовые файлы после экспорта

Ошибка:

Exception in thread "main" java.lang.ExceptionInInitializerError 
     at engineTester.Main.main(Main.java:22) 
     Caused by: java.lang.NullPointerException 
      at com.hybridia.engine3D.shaders.StaticShader.<clinit>(StaticShader.java:13) 
      ... 1 more 

Линия 22 из engineTester.Main.main находится где StaticShader инициализируется.

Файл, код нисходит (строка с ошибкой имеет комментарий рядом с ним):

package com.hybridia.engine3D.shaders; 
    import java.net.URL; 

    import org.lwjgl.util.vector.Matrix4f; 

    public class StaticShader extends ShaderProgram { 

    private int location_transformationLocaiton; 

    private static final String VERTEX_FILE = URL.class.getClass().getClassLoader() 
      .getResource("/resc/shaders/vertexShader.txt").toString(); //Error Here 
    private static final String FRAGMENT_FILE = URL.class.getClass().getClassLoader() 
      .getResource("/resc/shaders/fragmentShader.txt").toString(); 

    public StaticShader() { 
     super(VERTEX_FILE, FRAGMENT_FILE); 
    } 

    @Override 
    protected void bindAttributes() { 
     super.bindAttribute(0, "position"); 
     super.bindAttribute(1, "textureCoords"); 
    } 

    @Override 
    protected void getAllUniformLocations() { 
     location_transformationLocaiton = super.getUniformLocation("transformationMatrix"); 

    } 

    public void loadTransformation(Matrix4f matrix) { 
     super.loadMatrix(location_transformationLocaiton, matrix); 
    } 

} 

(Там же ошибка следующая строка (FRAGMENT_FILE), но фиксируя первый зафиксирует второй .)

То, что я пытаюсь сделать:

экспортировать этот проект в качестве JAR, который будет использоваться для моих будущих 3D-проектов. Однако, когда я запускаю его в своем тестовом проекте, я получаю ошибку выше. Я пробовал несколько методов (показано ниже), но я либо получаю Null Pointer exception, либо File Not Found exception. Класс StaticShader наследует от класса ShaderProgam, который принимает VERTEX_FILE и FRAGMENT_FILE и использует код GLSL для выполнения своих задач с помощью VAO и VBOs.

Я знаю, что проблема в строке 13 (строка с комментарием //Error Here). Почему-то все, что я пытался сделать, терпит неудачу. Я знаю, что файлы существуют на 100%, потому что в ссылочных библиотеках тестового проекта я вижу «vertexShader.txt» и «fragmentShader.txt». Я (буквально) поместил два файла в программу, надеясь, что он сможет быть прочитан StaticShader/ShaderProgram. Я создал папку для двух текстовых файлов, и папка находится отдельно от пути сборки.

Я бы разместил изображение иерархии, чтобы оно выглядело красивым и было легче понять, но у меня нет такой репутации. Это лучшее представление иерархии без картины:

SpaghettiEngineMKIII 
| 
| 
| 
|com.hybridia.engine3D.shaders 
|  |ShaderProgram 
|  |StaticShader 
| 
| 
|resc 
    |shaders 
     |vertexShader.txt 
     |fragmentShader.txt 

методы Я попытался решить эту проблему: (только немного доказательства я попытался фиксируя ошибку на моем)

  • InputStream
  • InputStream и BufferedReader
  • URL
  • InputStream и URL
  • Передача строки через super без использования URL/InputStream

Для Повтора/TL; DR:

Я экспортировал этот проект и сделал его JAR-файл. Я добавил JAR к пути сборки тестового проекта для проверки пределов рендеринга. Тем не менее, шейдерные файлы не могут быть найдены/доступны при запуске тестового проекта, несмотря на постоянное изменение кода поиска в классе StaticShader. Может ли это быть причиной неправильного или не относительного пути или есть другой способ, которым я должен захватить текстовые файлы из того, что я сделал?

Краткая история: проект отлично работал, когда StaticShader находился в тестовом проекте, а не в проекте игрового движка. Я переместил его, потому что, когда я закодировал, мне нужно было ссылаться на StaticShader в других классах самого движка.

Прошу прощения, если что-то отрывается как «быстро», я не собираюсь этого делать.

EDIT:

ShaderProgram фактически читает файлы, то StaticShader находит файлы и делает все прикольные вещи создания РВО. Я забыл упомянуть об этом раньше.

ответ

0

NPE, похоже, поступает с ресурса. Похоже, загрузчик классов для URL-адреса не совпадает с тем, который содержит ваш файл jar. Пытались ли вы изменение линии ошибки это ?:

private static final String VERTEX_FILE = StaticShader.class.getClass().getClassLoader() 
      .getResource("/resc/shaders/vertexShader.txt").toString(); 

StaticShader.class входит в том же банке файл как текстовый файл, так что я бы ожидать, что это работает ...

+0

Это не сработало на удивление. Он возвращает NPE; тот же, что и раньше, в том же месте. Папка 'resc' отображается в библиотеке в пути сборки. Должен ли я сделать это исходной папкой вместо библиотеки и посмотреть, работает ли она? – Mike

0

Вашей проблемы здесь

URL.class.getClass() ... 

Вы задаете систему для класса из URL.class который возвращает java.lang.Class.clas s класс. Тогда происходит загрузчик классов для . Java.lang.Class.class не может найти ваш ресурс относительно того, где загружаются байты для java.lang.Class.class.

Используя предложения от h3f3st0, вы хотите использовать класс, который находится внутри файла фляги так изменить вызов

private static final String VERTEX_FILE = StaticShader.class.getClassLoader() 
     .getResource("/resc/shaders/vertexShader.txt").toString(); 

и посмотреть, если это не поможет.

EDIT:

Опция, которая работает для меня, как указано в комментариях, используйте getResourceAsStream() вместо getResource().

+0

Все еще возвращает NPE. Может быть, я должен разместить два файла txt где-то еще/в папке src или сделать папку resc исходной папкой вместо папки библиотеки? – Mike

+0

Если ваша иерархия выше является макетом вашей банки, это кажется прекрасным, я знаю, что когда я упаковываю активы в банку, то, что я обычно использую, больше похож на AssetManager.class.getResourceAsStream («/ full/path/to/asset.gi "), чтобы получить InputStream, если это не является нулевым, прочитайте данные. – Jere

+0

Этот метод использования InputStream работал! Большое спасибо! Я не уверен, как мне следует продолжить ... Должен ли я написать ответ на свой вопрос, говоря, что я сделал, или дождаться, когда вы обновите/сделаете новый ответ, увидев, как я использовал ваш метод InputStream? – Mike

Смежные вопросы