diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java index 98f324658f..f70482bae1 100644 --- a/core/java/src/net/i2p/I2PAppContext.java +++ b/core/java/src/net/i2p/I2PAppContext.java @@ -149,6 +149,26 @@ public class I2PAppContext { return _globalAppContext; } + /** + * Sets the default context, unless there is one already. + * NOT a public API, for use by RouterContext only, NOT for external use. + * + * @param ctx context constructed with doInit = false + * @return success (false if previously set) + * @since 0.9.33 + */ + protected static boolean setGlobalContext(I2PAppContext ctx) { + synchronized (I2PAppContext.class) { + if (_globalAppContext == null) { + _globalAppContext = ctx; + return true; + } + } + System.out.println("Warning - New context not replacing old one, you now have a second one"); + (new Exception("I did it")).printStackTrace(); + return false; + } + /** * Pull the default context, WITHOUT creating a new one. * Use this in static methods used early in router initialization, @@ -190,10 +210,13 @@ public class I2PAppContext { * additional resources and threads, and may be the cause of logging * problems or hard-to-isolate bugs. * + * NOT a public API, for use by RouterContext only, NOT for external use. + * * @param doInit should this context be used as the global one (if necessary)? * Will only apply if there is no global context now. + * @since protected since 0.9.33, NOT for external use */ - private I2PAppContext(boolean doInit, Properties envProps) { + protected I2PAppContext(boolean doInit, Properties envProps) { synchronized (I2PAppContext.class) { _overrideProps = new I2PProperties(); if (envProps != null) @@ -311,12 +334,9 @@ public class I2PAppContext { ******/ if (doInit) { - if (_globalAppContext == null) { - _globalAppContext = this; - } else { - System.out.println("Warning - New context not replacing old one, you now have a second one"); - (new Exception("I did it")).printStackTrace(); - } + // Bad practice, sets a static field to this in constructor. + // doInit will be false when instantiated via Router. + setGlobalContext(this); } } // synch } diff --git a/history.txt b/history.txt index f1c40d7db2..821a1ae700 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,20 @@ +2017-11-26 zzz + * Context: Hopefully fix rare NPE on Android (ticket #2092) + +2017-11-25 zzz + * Console: + - Show full logger.config path on /configlogging + - Don't say 'Plugin downloaded' when installing from file + * Debian: + - Replace glassfish-javaee with libtaglibs-standard-* (ticket #2093) + - Remove libecj-java dependency (ticket #2094) + +2017-11-23 zzz + * i2ptunnel: Add timeout to header reads for CONNECT, HTTP, and SOCKS clients + * Wrapper 3.5.34 + 2017-11-22 zzz + * i2psnark: Fix nbsp in logs on config change (ticket #2082) * Streaming: Fix bug causing loopback hangs and preventing desired ack behavior (ticket #1939) * Tomcat 8.5.23 diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index c3ea5f9f5b..95038bd868 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -308,7 +308,8 @@ public class Router implements RouterClock.ClockShiftListener { // i2p.dir.log defaults to i2p.dir.router // i2p.dir.pid defaults to i2p.dir.router // i2p.dir.base defaults to user.dir == $CWD - _context = new RouterContext(this, envProps); + _context = new RouterContext(this, envProps, false); + RouterContext.setGlobalContext(_context); _eventLog = new EventLog(_context, new File(_context.getRouterDir(), EVENTLOG)); // This is here so that we can get the directory location from the context diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java index ac15c1be43..eb94d3fe49 100644 --- a/router/java/src/net/i2p/router/RouterContext.java +++ b/router/java/src/net/i2p/router/RouterContext.java @@ -84,7 +84,20 @@ public class RouterContext extends I2PAppContext { * Caller MUST call initAll() after instantiation. */ public RouterContext(Router router, Properties envProps) { - super(filterProps(envProps)); + this(router, envProps, true); + } + + /** + * Caller MUST call initAll() after instantiation. + * NOT a public API, for use by Router only, NOT for external use. + * + * @param doInit should this context be used as the global one (if necessary)? + * Will only apply if there is no global context now. + * If false, caller should call setGlobalContext() afterwards. + * @since 0.9.33 + */ + RouterContext(Router router, Properties envProps, boolean doInit) { + super(doInit, filterProps(envProps)); _router = router; // Disabled here so that the router can get a context and get the // directory locations from it, to do an update, without having @@ -94,7 +107,24 @@ public class RouterContext extends I2PAppContext { if (!_contexts.isEmpty()) System.err.println("Warning - More than one router in this JVM"); _finalShutdownTasks = new CopyOnWriteArraySet(); - _contexts.add(this); + if (doInit) { + // Bad practice, adding this to static List in constructor. + // doInit will be false when instantiated via Router. + _contexts.add(this); + } + } + + /** + * Sets the default context, unless there is one already. + * NOT a public API, for use by Router only, NOT for external use. + * + * @param ctx context constructed with doInit = false + * @return success (false if previously set) + * @since 0.9.33 + */ + static boolean setGlobalContext(RouterContext ctx) { + _contexts.add(ctx); + return I2PAppContext.setGlobalContext(ctx); } /** diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index a6204817e3..f2522cd4ed 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 8; + public final static long BUILD = 9; /** for example "-test" */ public final static String EXTRA = "";