gradle generate jar имеет файл ресурсов, но запуск jar вызывает недопустимый ресурс - PullRequest
1 голос
/ 10 июля 2020

У меня есть сервер отдыха, написанный на java и использующий gradle в качестве системы сборки.

В одном из моих классов я использую файл src / main / resources / myresource.config как показано ниже

public static void main(String[] args) {
  String resourcePath = Myapplication.class.getClassLoader().getResource("myresource.config").toURI().getPath();
LOGGER.info(String.format("Loading data from config %s", resourcePath));
BufferedReader br = new BufferedReader(new FileReader(resourcePath));
}

Программа отлично работает при запуске класса непосредственно из командной строки или ide.

Я создаю банку для своего приложения, как показано ниже

jar {
    manifest {
        attributes 'Main-Class': 'com.example.Myapplication',
                'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
    }

    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}

jar успешно собирается внутри build / libs, когда я пытаюсь запустить jar java -jar myapplication.jar Мне не удается найти ресурс myresource.config .

Я распаковал архив сборки и обнаружил, что файл myresource.config присутствует, но jar не запускается.

То, что я пробовал до сих пор

ClassLoader.getSystemClassLoader().getResource("myresource.config");
Thread.currentThread().getContextClassLoader().getResource("myresource.config")

Кто-нибудь может указать, что я делаю неправильно?

Stacktrace

INFO: Loading data from config null
Invalid resource: myresource.config
java.lang.NullPointerException
    at java.io.FileInputStream.<init>(FileInputStream.java:130)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at java.io.FileReader.<init>(FileReader.java:58)
    at com.example.Myapplication.<main>(Myapplication.java:26)

Ответы [ 2 ]

2 голосов
/ 11 июля 2020

Проблема в том, что при запуске приложения из IDE myresource.config читается прямо из файловой системы. То есть вы получаете обычный URL-адрес файла:

URL configUrl = Myapplication.class.getClassLoader().getResource("myresource.config");
// returns "file:/C:/path/to/project/bin/main/myresource.config"

Но когда вы запускаете приложение из файла jar, файл конфигурации считывается из jar, и вы получаете URL-адрес на основе jar:

URL configUrl = Myapplication.class.getClassLoader().getResource("myresource.config");
// returns "jar:file:/C:/path/to/project/build/libs/myapplication.jar!/myresource.config"

Этот второй URL-адрес на основе jar не может быть преобразован в путь файловой системы, поэтому вы получаете null.

Чтобы получить конфигурацию в обоих сценариях ios, вы должны сделать что-то вроде этого

try (final InputStream configInputStream = Myapplication.class.getClassLoader().getResourceAsStream("myresource.config");
     final BufferedReader br = new BufferedReader(new InputStreamReader(configInputStream));) {
   // do something with br
}
0 голосов
/ 11 июля 2020

Я думаю, вы должны использовать вместо этого getResourceAsStream.
Myapplication.class.getResourceAsStream("myresource.config")

...