2016-08-08 6 views
4

Я получаю эту ошибку, когда я запускаю свою упакованную банку. Когда я запускаю его из своей IDE, он не дает ошибку и не запускается.Неверное имя файла, имени каталога или тома. - Kotlin - Maven

java.io.FileNotFoundException: file:\C:\Development\Kotlin\AccountTool\target\AccountTool-1.0-SNAPSHOT-jar-with-dependencies.jar!\accounts.json (The filename, directory name or volume label syntax is incorrect) 
    at java.io.FileInputStream.open0(Native Method) 
    at java.io.FileInputStream.open(Unknown Source) 
    at java.io.FileInputStream.<init>(Unknown Source) 
    at java.io.FileInputStream.<init>(Unknown Source) 
    at java.io.FileReader.<init>(Unknown Source) 
    at com.martacus.accounttool.ToolView$handler.readData(Tool.kt:41) 
    at com.martacus.accounttool.ToolView.<init>(Tool.kt:56) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) 
    at java.lang.reflect.Constructor.newInstance(Unknown Source) 
    at java.lang.Class.newInstance(Unknown Source) 
    at tornadofx.FXKt.find(FX.kt:238) 
    at tornadofx.App.start(App.kt:27) 
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(Unknown Source) 
    at com.sun.javafx.application.LauncherImpl$$Lambda$52/31866147.run(Unknown Source) 
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(Unknown Source) 
    at com.sun.javafx.application.PlatformImpl$$Lambda$45/2900468.run(Unknown Source) 
    at com.sun.javafx.application.PlatformImpl.lambda$null$170(Unknown Source) 
    at com.sun.javafx.application.PlatformImpl$$Lambda$48/4210449.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(Unknown Source) 
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/24077489.run(Unknown Source) 
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source) 
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
    at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source) 
    at com.sun.glass.ui.win.WinApplication$$Lambda$36/1828305.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 

код и файл иерархии в язя: enter image description here

fun readData(){ 
    accounts.clear() 
    var readFile = ToolView::class.java.classLoader.getResource("accounts.json").file 
    println(readFile) 
    FileReader(readFile).use{ 
     var account = gson.fromJson(it, Array<Account>::class.java) ?: return 
     for(i in account){ 
      accounts.add(i) 
     } 
    } 

} 

.jar корень:

enter image description here

Я понятия не имею, что происходит не так и почему она дает меня ошибка. Поиск в stackoverflow и google не дал мне правильный ответ. Я надеюсь, что кто-то здесь может мне помочь, если вам нужна дополнительная информация, скажите об этом.

Спасибо!

ответ

5

Когда ресурс упакован в банку, он больше не доступен в виде файла в файловой системе. Поэтому вы не можете использовать стандартный API для работы с файловой системой как File() или FileReader() для доступа к содержимому ресурса.

Вместо этого вы должны открыть поток ресурсов с Class.getResourceAsStream или ClassLoader.getResourceAsStream методами и читать содержимое из этого потока:

val stream = ToolView::class.java.classLoader.getResourceAsStream("accounts.json") 

stream.reader().use { 
    println(it.readText()) 
} 
+1

может также должны начинаться с префикса '/' как '/ accounts.json', потому что это не в том же пакете, что и ToolView (опять-таки я не знаю, какой пакет ToolView находится). Или вместо этого используйте системный загрузчик классов. –

+0

@JaysonMinard Я считаю, что это необходимо, когда 'getResourceAsStream' вызывается на экземпляр класса, который разрешает имя ресурса относительно его пакета. И здесь 'getResourceAsStream' вызывается на' ClassLoader'. Но в любом случае спасибо за разъяснения. – Ilya

+0

Спасибо! Оно работает! Но применимо ли это также к WriteFile? Так как я не изменил, я получил ошибку при записи. Atlough я не вижу метод stream.writer(). – Martacus