简体   繁体   中英

Creating Runnable Jar with external text and ser files included

Well, I tried so many ways to create executable jar, but after 4 hours I give up. I am trying to make executable jar file with my project where main class is in the controller. Basically I tried with export/runnable JAR file with various options including generating of ant script . I always have similar errors in terminal

When I'm running that with terminal with

java -jar fruitStore.jar

it says

    bmj@OZ:~/Documents$ java -jar fruitStoreApp.jar 
java.io.FileNotFoundException: customers.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadCustomers(Shop.java:250)
    at model.Shop.<init>(Shop.java:121)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: users.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadUsers(Shop.java:210)
    at model.Shop.<init>(Shop.java:122)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: suppliers.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadSuppliers(Shop.java:190)
    at model.Shop.<init>(Shop.java:123)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: stocks.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadStock(Shop.java:230)
    at model.Shop.<init>(Shop.java:124)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: sales.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadSales(Shop.java:150)
    at model.Shop.<init>(Shop.java:126)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: orders.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadOrders(Shop.java:170)
    at model.Shop.<init>(Shop.java:127)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: javax.imageio.IIOException: Can't read input file!
    at javax.imageio.ImageIO.read(ImageIO.java:1301)
    at GUI.WelcomeScreenGUI.<init>(WelcomeScreenGUI.java:33)
    at model.View.<init>(View.java:51)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    ... 5 more

I know where is the problem. It doesn't attach marked files on the picture to the jar

带有所需文件的图片

My question is: How to add that files ? Can you please give me detailed answer for that. One condition. I can't change place of that files.

I read about some solutions with Maven which I would like to avoid due to lack of knowledge of Maven.

Thanks in advance for quick reply

After going through your code, I see you have your file names set and you are using FileInputStream which reads from the file system.

private String saleFile = "sales.ser";
...
public void loadSales(String inPutFile) {
    try {
        FileInputStream fileIn = new FileInputStream(inPutFile);

So what's going to happen is the program will look for sale.ser in the current working directory. In your IDE normally the working directory is the project root, which is where your files are, that's why it works.

So since you can't change the code, here are some suggestions.

When you run the jar, you need to run the jar from the current working directory. When you export the jar export it to the project root. And when you run, make sure you're in the project root

Probably a better approach would be to write script to launch the program (which is pretty common). This will allow more flexibility to how/where you launch the app. I'm not the greatest at writing scripts so I'll just put the most basic, but you may want to may it more complex based on how you want to launch the app and locate resources. With the .bat file example below, the .bat file should also be in the project root

@echo off
setlocal

if "%JAVACMD%" == "" set JAVACMD=%JAVA_HOME%\bin\java.exe
if "%FRUITSTAND_HOME%" == "" set FRUITSTAND_HOME=%~dp0

cd "%FRUITSTAND_HOME%"
"%JAVACMD%" -cp "%FRUITSTAND_HOME%\lib\*" -jar "%FRUITSTAND_HOME%\fruitStoreApp.jar"
endlocal

You then (from the project root) simply run fruitStoreApp.bat .

I tested it and it works. I just get FileNotFoundException for the stocks.ser sales.ser and order.ser , because... well they don't exist (in your project - at least not in your github).

Also looks like you're using bash so you will have write a simple bash script. I would create both .bat and .sh files, which is pretty common, to enable Windows and Unix users access

The easiest thing to do is to extract your existing JAR file, include those folders with the external text and ser files, and repackage your JAR .

  1. Make a copy of your original fruitStoreApp.jar somewhere in case things go wrong.
  2. To extract a JAR file from command line, run jar xf fruitStoreApp.jar .
  3. Copy your model folder (and whatever else) over.
  4. Remove your old fruitStoreApp.jar so it doesn't get included in the next re-jar step.
  5. To re-jar all your artifacts by running jar cf fruitStoreApp.jar * .

Using ANT

If you want to try this with ant , you can include the fileset type in your jar task like this:

<target name="package">
    <jar destfile="fruitStoreApp.jar" >
        <fileset dir="classes"/>
        <fileset dir="model" />
        <fileset dir="images" />
        <fileset dir="GUI" />
    </jar>
</target>

This will jar all files in the classes , model , images , GUI folders together into a file called fruitStoreApp.jar . I am assuming that all your .class files are within the classes folder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM