URI is not hierarchical exception when running app

2019-08-08 18:29发布

I've exported my Java console application to a Jar file, but when I run the jar and call code that parses in a JSON file I get a java.lang.IllegalArgumentException

Does anyone know why the exception is being thrown when I run the program as a JAR? The parsing works fine when the application is run from Eclipse.

This is the exact error that is output when I execute the jar file and call the code that parses the JSON file:

Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierar
chical
        at java.io.File.<init>(Unknown Source)
        at gmit.GameParser.parse(GameParser.java:44)
        at gmit.Main.main(Main.java:28)

This is how the parsing is being done in my GameParser class:

public class GameParser {
    private static final String GAME_FILE = "/resources/game.json";
    private URL sourceURL = getClass().getResource(GAME_FILE); 
    private int locationId;

    private List<Location> locations;
    private List<Item> items;
    private List<Character> characters;

    public void parse() throws IOException, URISyntaxException {
        ObjectMapper mapper = new ObjectMapper();
       mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        try {                   
            // read from file, convert it to Location class
            Location loc = new Location();
            loc = mapper.readValue(new File(sourceURL.toURI()), Location.class);
            Item item = mapper.readValue(new File(sourceURL.toURI()), Item.class);
            GameCharacter character = mapper.readValue(new File(sourceURL.toURI()), GameCharacter.class);

            // display to console
            System.out.println(loc.toString());
            System.out.println(item.toString());
            System.out.println(character.toString());
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

This is the folder structure of my project:

source tree

2条回答
不美不萌又怎样
2楼-- · 2019-08-08 18:49

The call getClass().getResource(GAME_FILE); will return a URL relative to this class. If you are executing your program from a JAR file, it will return a URL pointing to a JAR file.

Files in java can only represent direct filesystem files, not the ones in zip/jar archives.

To fix it:

  1. Try to use getClass().getResourceAsStream() and use that instead of Files or
  2. extract the files into some directory and use File in the same way as you are trying now.
查看更多
不美不萌又怎样
3楼-- · 2019-08-08 19:13

This problem happen when you have two files with the same name,i mean in your project you have folder whith name "Images" and in your desktop you have other folder his name "images" automatically JVM choose desktop folder ,so if you want to confirm try to print your URI.Use this example to show your URI before creating your file

try {
    URL location = this.getClass().getResource("/WavFile");
    System.out.println(location.toURI());
     File file = new File(location.toURI()); 
     if (!file.exists()) {
        System.out.println(file.mkdirs());
        System.out.println(file.getAbsoluteFile());
    }else
    {
         System.out.println(file.getPath());
    }
} catch (Exception e) {
    e.printStackTrace();
}
查看更多
登录 后发表回答