What I can do is make Nxt.shutdown() public and not add any shutdown hooks myself, when started using init(), only when started using main(). Then whoever calls init() has the responsibility to add a shutdown hook or call shutdown().
I don't know how your restart works, but unless the jvm is really shutdown and started again, init() is unlikely to work as expected after a shutdown(), because of all the static initializers and final variables I rely on.
Perfect! Our client is built as an Eclipse RCP app, those come with a native launcher that controls the jvm. Thats how Eclipse can be *restarted* when you installed a new plugin. It's just that jvm shutdown seems to not go so gentle.
The nxt-default.properties has to be there. I don't throw exceptions if nxt.properties is missing. Why do you not want to use nxt-default.properties? It only needs to be in the classpath, it can be hidden from the user.
...
This cannot be done in init, because properties must be loaded before any other classes attempt to get them using Nxt.getStringProperty() etc., such as the Logger initializing its debug and enableStackTraces as static final. Allowing additional properties overrides in the init() was not such a good idea. If you want to add listeners to BlockchainProcessor for example, before init() has been called, it still needs to see the correct values of all properties - so it is too late to set them in init().
In an RCP application everything gets bundled as an OSGI bundle/plugin, we also do this for nxt. It's so we can deploy updates to nxt as only one updated plugin. This however leads to troubles since an OSGI bundle is usually a jar and it's kinda hidden away in the plugins folder (not easily reachable for end users). Currently we already have a properties file in the install folder root (which is recognizably named after the client) it would be most ideal if we can use that properties file to allow for user overwrites, this is also the case since we are planning to support multiple crypto currencies in the client and all user settings could go there.
I'm not sure if `ClassLoader.getSystemResourceAsStream("nxt.properties");` will include the install directory in it's search path since nxt is *in* it's own plugin which is loaded by the OSGI classloader (maybe it will).
Ideal would be if somehow you could make the location of nxt.properties dynamic. Easiest in our case would probably be a simple property (System.getProperty('nxt.Nxt.config')) so we can pass the location as jvm argument or set it ourselves in code that loads before the nxt plugin is activated.