To package an application means putting the classes in a .jar file, which is a zip file with one or more special Java-specific entries in it. (There are many Stack Overflow answers describing how to do this, such as Java: export to an .jar file in eclipse . Feel free to search for more.)
The problem is, an application cannot write to its own .jar file. On Windows the file is likely to be locked and unwritable; on other systems, it may be possible but is a bad idea for many reasons. You should always consider a .jar file read-only.
Since the configuration needs to be writable, it cannot live in your .jar file, but your .jar file can (and should) include your config.json as a default configuration. The actual configuration should be a file somewhere under the user’s home directory; if it doesn’t exist, your program should copy your default configuration to that location to allow future modification. Alternatively, your program could just ignore missing configuration and default to reading your internally packaged default configuration, but in that case, you’d want to provide thorough documentation of the writable configuration file’s format for end users, since they won’t have an example to go by.
Files packaged inside a .jar file are called resources and are read using the Class.getResource or Class.getResourceAsStream method. You cannot read them using File or Path objects, because they are parts of a zip archive, not actual files. Copying it to a writable location typically looks like this:
Path userConfigFile = /* ... */;
try (InputStream defaultConfig = getClass().getResourceAsStream("/config/config.json")) {
Files.copy(defaultConfig, userConfigFile);
}
For more information on reading resources, you may want to read about Access to Resources.
On Windows, the actual location of a configuration file is usually in a subdirectory of the user’s AppData directory:
Path configParent;
String appData = System.getEnv("APPDATA");
if (appData != null) {
configParent = Paths.get(appData);
} else {
configParent = Paths.get(
System.getProperty("user.home"), "AppData", "Local");
}
Path configDir = configParent.resolve(applicationName);
Files.createDirectories(configDir);
Path userConfigFile = configDir.resolve("config.json");
If you’re interested in discussion of where to place user configuration files on other platforms, see this question and this one.