java.lang.Object
net.i2p.I2PAppContext
Direct Known Subclasses:
RouterContext

public class I2PAppContextextends Object

Provide a base scope for accessing singletons that I2P exposes. Rather than using the traditional singleton, where any component can access the component in question directly, all of those I2P related singletons are exposed through a particular I2PAppContext. This helps not only with understanding their use and the components I2P exposes, but it also allows multiple isolated environments to operate concurrently within the same JVM - particularly useful for stubbing out implementations of the rooted components and simulating the software's interaction between multiple instances.

As a simplification, there is also a global context - if some component needs access to one of the singletons but doesn't have its own context from which to root itself, it binds to the I2PAppContext's getGlobalContext(), which is the first context that was created within the JVM, or a new one if no context existed already. This functionality is often used within the I2P core for. logging - e.g.

    private static final Log _log = new Log(someClass.class);
It is for this reason that applications that care about working with multiple contexts should build their own context as soon as possible (within the main(..)) so that any referenced components will latch on to that context instead of instantiating a new one. However, there are situations in which both can be relevant.
  • Field Details

    • _globalAppContext

      protected static volatile I2PAppContext _globalAppContext
      The context that components without explicit root are bound.
    • _overrideProps

      protected final I2PProperties _overrideProps
      Override properties for this context.
    • _mergedProps

      private volatile Properties _mergedProps
      Config properties merged with the system properties.
    • _statManager

      private StatManager _statManager
      The context's stat manager, created on demand.
    • _sessionKeyManager

      protected SessionKeyManager _sessionKeyManager
      The session key manager.
    • _namingService

      private NamingService _namingService
      The context's naming service, created on demand.
    • _elGamalEngine

      private ElGamalEngine _elGamalEngine
      The context's ElGamal engine, created on demand.
    • _AESEngine

      private AESEngine _AESEngine
      The context's AES engine, created on demand.
    • _logManager

      private LogManager _logManager
      The context's log manager, created on demand.
    • _hmac256

      private HMAC256Generator _hmac256
      The context's HMAC-SHA256 generator, created on demand.
    • _sha

      private SHA256Generator _sha
      The context's SHA-256 generator, created on demand.
    • _clock

      protected Clock _clock
      The context clock, overridden in RouterContext.
    • _dsa

      private DSAEngine _dsa
      The context's DSA engine, created on demand.
    • _random

      private RandomSource _random
      The context's secure random source, created on demand.
    • _keyGenerator

      private KeyGenerator _keyGenerator
      The context's key generator, created on demand.
    • _keyRing

      protected KeyRing _keyRing
      The key ring, overridden in RouterContext.
    • _simpleTimer2

      private SimpleTimer2 _simpleTimer2
      The context's shared timer, created on demand.
    • _portMapper

      private final PortMapper _portMapper
      The context's port mapper for UPnP.
    • _statManagerInitialized

      private volatile boolean _statManagerInitialized
      Whether the stat manager has been created.
    • _sessionKeyManagerInitialized

      protected volatile boolean _sessionKeyManagerInitialized
      Whether the session key manager has been initialized.
    • _namingServiceInitialized

      private volatile boolean _namingServiceInitialized
      Whether the naming service has been created.
    • _elGamalEngineInitialized

      private volatile boolean _elGamalEngineInitialized
      Whether the ElGamal engine has been created.
    • _AESEngineInitialized

      private volatile boolean _AESEngineInitialized
      Whether the AES engine has been created.
    • _logManagerInitialized

      private volatile boolean _logManagerInitialized
      Whether the log manager has been created.
    • _hmac256Initialized

      private volatile boolean _hmac256Initialized
      Whether the HMAC generator has been created.
    • _shaInitialized

      private volatile boolean _shaInitialized
      Whether the SHA generator has been created.
    • _clockInitialized

      protected volatile boolean _clockInitialized
      Whether the clock is initialized, used in RouterContext.
    • _dsaInitialized

      private volatile boolean _dsaInitialized
      Whether the DSA engine has been created.
    • _randomInitialized

      private volatile boolean _randomInitialized
      Whether the random source has been created.
    • _keyGeneratorInitialized

      private volatile boolean _keyGeneratorInitialized
      Whether the key generator has been created.
    • _keyRingInitialized

      protected volatile boolean _keyRingInitialized
      Whether the key ring is initialized, used in RouterContext.
    • _simpleTimer2Initialized

      private volatile boolean _simpleTimer2Initialized
      Whether the shared timer has been created.
    • _shutdownTasks

      protected final Set<Runnable> _shutdownTasks
      Shutdown tasks to run on context shutdown.
    • _baseDir

      private final File _baseDir
      The installation's base directory.
    • _configDir

      private final File _configDir
      Directory holding i2p.properties.
    • _routerDir

      private final File _routerDir
      Directory holding the router's egress files.
    • _pidDir

      private final File _pidDir
      Directory for pid files.
    • _logDir

      private final File _logDir
      Directory holding the log files.
    • _appDir

      private final File _appDir
      Directory of the running application.
    • _tmpDir

      private volatile File _tmpDir
      Directory for scratch files.
    • _libDir

      private final File _libDir
      Directory holding the jar files.
    • _tmpDirRand

      private final Random _tmpDirRand
      Random for unique temp directory names.
    • _appManager

      private final ClientAppManager _appManager
      The context's client app manager.
    • _lock1

      private final Object _lock1
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock2

      private final Object _lock2
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock3

      private final Object _lock3
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock4

      private final Object _lock4
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock5

      private final Object _lock5
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock7

      private final Object _lock7
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock8

      private final Object _lock8
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock10

      private final Object _lock10
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock11

      private final Object _lock11
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock12

      private final Object _lock12
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock13

      private final Object _lock13
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock14

      private final Object _lock14
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock16

      private final Object _lock16
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock17

      private final Object _lock17
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
    • _lock20

      private final Object _lock20
      Guards for the lazily created context components, split from one big lock to avoid deadlocks.
  • Constructor Details

    • I2PAppContext

      public I2PAppContext()
      Create a brand new context. WARNING: In almost all cases, you should use getGlobalContext() instead, to avoid creating additional contexts, which may spawn numerous additional resources and threads, and may be the cause of logging problems or hard-to-isolate bugs.
    • I2PAppContext

      public I2PAppContext(Properties envProps)
      Create a brand new context. WARNING: In almost all cases, you should use getGlobalContext() instead, to avoid creating additional contexts, which may spawn numerous additional resources and threads, and may be the cause of logging problems or hard-to-isolate bugs.
      Parameters:
      envProps - environment properties, may be null
    • I2PAppContext

      protected I2PAppContext(boolean doInit, Properties envProps)
      Create a brand new context. WARNING: In almost all cases, you should use getGlobalContext() instead, to avoid creating additional contexts, which may spawn numerous 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.

      Parameters:
      doInit - should this context be used as the global one (if necessary)? Will only apply if there is no global context now.
      envProps - environment properties, may be null
  • Method Details

    • getGlobalContext

      public static I2PAppContext getGlobalContext()
      Pull the default context, creating a new one if necessary, else using the first one created.

      Warning - do not save the returned value, or the value of any methods below, in a static field, or you will get the old context if a new router is started in the same JVM after the first is shut down, e.g. on Android.

      Returns:
      the global context for this JVM
    • setGlobalContext

      protected static boolean setGlobalContext(I2PAppContext ctx)
      Default context, unless there is one already. NOT a public API, for use by RouterContext only, NOT for external use.
      Parameters:
      ctx - context constructed with doInit = false
      Returns:
      success (false if previously set)
    • getCurrentContext

      public static I2PAppContext getCurrentContext()
      Pull the default context, WITHOUT creating a new one. Use this in static methods used early in router initialization, where creating a context messes things up.
      Returns:
      context or null
    • getBaseDir

      public File getBaseDir()
      This is the installation dir, often referred to as $I2P. Applications should consider this directory read-only and never attempt to write to it. It may actually be read-only on a multi-user installation. The config files in this directory are templates for user installations and should not be accessed by applications. The only thing that may be useful in here is the lib/ dir containing the .jars.
      Returns:
      dir constant for the life of the context
    • getConfigDir

      public File getConfigDir()
      The base dir for config files. Applications may use this to access router configuration files if necessary. Usually ~/.i2p on Linux and %APPDIR%\I2P on Windows. In installations originally installed with 0.7.5 or earlier, and in "portable" installations, this will be the same as the base dir.
      Returns:
      dir constant for the life of the context
    • getRouterDir

      public File getRouterDir()
      Where the router keeps its files. Applications should not use this. The same as the config dir for now.
      Returns:
      dir constant for the life of the context
    • getPIDDir

      public File getPIDDir()
      Where router.ping goes. Applications should not use this. The same as the router dir by default as of 0.8.12 Was the same as the system temp dir prior to that. Which was a problem for multi-user installations.
      Returns:
      dir constant for the life of the context
    • getLogDir

      public File getLogDir()
      Where the router keeps its log directory. Applications should not use this. The same as the config dir for now. (i.e. ~/.i2p, NOT ~/.i2p/logs).
      Returns:
      dir constant for the life of the context
    • getAppDir

      public File getAppDir()
      Where applications may store data. The same as the config dir for now, but may change in the future. Apps should be careful not to overwrite router files.
      Returns:
      dir constant for the life of the context
    • getTempDir

      public final File getTempDir()
      Where anybody may store temporary data. This is a directory created in the system temp dir on the first call in this context, and is deleted on JVM exit. Applications should create their own directory inside this directory to avoid collisions with other apps.
      Returns:
      dir constant for the life of the context
    • getLibDir

      public File getLibDir()
      This is the library dir, which is usually $I2P/lib. It contains all the jars (i.e. the classpath). Most applications will not need this, and must treat this directory as read-only.
      Returns:
      dir constant for the life of the context
    • deleteTempDir

      public void deleteTempDir()
      Don't rely on deleteOnExit().
    • cleanupStaleTempDirs

      private void cleanupStaleTempDirs()
      Clean up stale i2p- temp directories from previous sessions. Since we're starting a new session, all existing i2p-*.tmp folders are from previous sessions and can be safely deleted.
    • getProperty

      public String getProperty(String propName)
      Access the configuration attributes of this context, using properties provided during the context construction, or falling back on System.getProperty if no properties were provided during construction (or the specified prop wasn't included).
      Parameters:
      propName - the property name
      Returns:
      the property value, or null
    • getProperty

      public String getProperty(String propName, String defaultValue)
      Access the configuration attributes of this context, using properties provided during the context construction, or falling back on System.getProperty if no properties were provided during construction (or the specified prop wasn't included).
      Parameters:
      propName - the property name
      defaultValue - the default value
      Returns:
      the property value, or the default
    • getProperty

      public int getProperty(String propName, int defaultVal)
      Return an int with an int default.
      Parameters:
      propName - the property name
      defaultVal - the default value
      Returns:
      the property value, or the default
    • getProperty

      public long getProperty(String propName, long defaultVal)
      Return a long with a long default.
      Parameters:
      propName - the property name
      defaultVal - the default value
      Returns:
      the property value, or the default
    • getProperty

      public final float getProperty(String propName, float defaultVal)
      Return a float with a float default.
      Parameters:
      propName - the property name
      defaultVal - the default value
      Returns:
      the property value, or the default
    • getProperty

      public final boolean getProperty(String propName, boolean defaultVal)
      Return a boolean with a boolean default.
      Parameters:
      propName - the property name
      defaultVal - the default value
      Returns:
      the property value, or the default
    • getBooleanProperty

      public boolean getBooleanProperty(String propName)
      Default false.
      Parameters:
      propName - the property name
      Returns:
      the boolean property
    • getBooleanPropertyDefaultTrue

      public boolean getBooleanPropertyDefaultTrue(String propName)
      Boolean property, defaulting to true if not set.
      Parameters:
      propName - the property name
      Returns:
      the boolean property default true
    • getPropertyNames

      public Set<String> getPropertyNames()
      Access the configuration attributes of this context, listing the properties provided during the context construction, as well as the ones included in System.getProperties.

      WARNING - not overridden in RouterContext, doesn't contain router config settings, use getProperties() instead.

      Returns:
      set of Strings containing the names of defined system properties
    • getProperties

      public Properties getProperties()
      Access the configuration attributes of this context, listing the properties provided during the context construction, as well as the ones included in System.getProperties.
      Returns:
      new Properties with system and context properties
    • addPropertyCallback

      public void addPropertyCallback(I2PProperties.I2PPropertyCallback callback)
      Add a callback, which will fire upon changes in the property given in the specific callback.

      This is an intentional no-op in a plain I2PAppContext: its properties are only populated in the constructor, so there is nothing to notify. A subclass that allows properties to change at runtime overrides this to register the callback with its I2PProperties - see RouterContext.addPropertyCallback(I2PProperties.I2PPropertyCallback). Callers that depend on property-change notifications must therefore only do so in such a context.

      Parameters:
      callback - The implementation of the callback.
    • statManager

      public StatManager statManager()
      The statistics component with which we can track various events over time.
      Returns:
      the stat manager
    • initializeStatManager

      private void initializeStatManager()
      Creates the stat manager from the config.
    • sessionKeyManager

      public SessionKeyManager sessionKeyManager()
      The session key manager which coordinates the sessionKey / sessionTag data. This component allows transparent operation of the ElGamal/AES+SessionTag algorithm, and contains all of the session tags for one particular application.

      This is deprecated for client use, it should be used only by the router as its own key manager. Not that clients are doing end-to-end crypto anyway.

      For client crypto within the router, use RouterContext.clientManager()getClientSessionKeyManager(dest)

      As of 0.9.15, this returns a dummy SessionKeyManager in I2PAppContext. The dummy SKM does NOT handle session tags. Overridden in RouterContext to return the full TransientSessionKeyManager.

      Returns:
      the session key manager
    • initializeSessionKeyManager

      protected void initializeSessionKeyManager()
      Initialize the session key manager.
    • namingService

      public NamingService namingService()
      Pull up the naming service used in this context. The naming service itself works by querying the context's properties, so those props should be specified to customize the naming service exposed.
      Returns:
      the naming service
    • initializeNamingService

      private void initializeNamingService()
      Creates the naming service from the config.
    • elGamalEngine

      public ElGamalEngine elGamalEngine()
      This is the ElGamal engine used within this context. While it doesn't really have anything substantial that is context specific (the algorithm just does the algorithm), it does transparently use the context for logging its performance and activity. In addition, the engine can be swapped with the context's properties (though only someone really crazy should mess with it ;).
      Returns:
      the ElGamal engine
    • initializeElGamalEngine

      private void initializeElGamalEngine()
      Creates the ElGamal engine.
    • aes

      public AESEngine aes()
      Ok, I'll admit it, there is no good reason for having a context specific AES engine. We don't really keep stats on it, since its just too fast to matter. Though for the crazy people out there, we do expose a way to disable it.
      Returns:
      the AES engine
    • initializeAESEngine

      private void initializeAESEngine()
      Creates the AES engine.
    • logManager

      public LogManager logManager()
      Query the log manager for this context, which may in turn have its own set of configuration settings (loaded from the context's properties). Each context's logManager keeps its own isolated set of Log instances with their own log levels, output locations, and rotation configuration.
      Returns:
      the log manager
    • initializeLogManager

      private void initializeLogManager()
      Creates the log manager from the config.
    • setLogManager

      public void setLogManager(LogManager logManager)
      Overwrites the LogManager instance to be used by the router. This should only be called after the Router is instantiated but before it is started. Calling this at any other time can have unpredictable side effects.
      Parameters:
      logManager - the LogManager instance to use
    • hmac256

      public HMAC256Generator hmac256()
      Un-deprecated in 0.9.38.
      Returns:
      the HMAC256 generator
    • sha

      public SHA256Generator sha()
      Our SHA256 instance (see the hmac discussion for why its context specific).
      Returns:
      the SHA256 generator
    • initializeSHA

      private void initializeSHA()
      Creates the SHA-256 generator.
    • dsa

      public DSAEngine dsa()
      Our DSA engine (see HMAC and SHA above).
      Returns:
      the DSA engine
    • initializeDSA

      private void initializeDSA()
      Creates the DSA engine.
    • keyGenerator

      public KeyGenerator keyGenerator()
      Component to generate ElGamal, DSA, and Session keys. For why it is in the appContext, see the DSA, HMAC, and SHA comments above.
      Returns:
      the key generator
    • initializeKeyGenerator

      private void initializeKeyGenerator()
      Creates the key generator.
    • clock

      public Clock clock()
      The context's synchronized clock, which is kept context specific only to enable simulators to play with clock skew among different instances.
      Returns:
      the context's Clock, initialized on the first call and shared by every caller
    • initializeClock

      protected void initializeClock()
      Initialize the clock.
    • routingKeyGenerator

      public RoutingKeyGenerator routingKeyGenerator()
      Determine how much do we want to mess with the keys to turn them into something we can route. This is context specific because we may want to test out how things react when peers don't agree on how to skew.

      As of 0.9.16, returns null in I2PAppContext. You must be in RouterContext to get a generator.

      Returns:
      null always
    • keyRing

      public KeyRing keyRing()
      Basic hash map.
      Returns:
      the key ring
    • initializeKeyRing

      protected void initializeKeyRing()
      Initialize the key ring.
    • random

      public RandomSource random()
      The random source for this context, created on first use.

      The first caller initializes it, holding a lock so that concurrent callers share one instance; every later caller gets that same object. The instance is a FortunaRandomSource, seeded from /dev/urandom and ./prngseed.rnd, so the first call may block while it gathers entropy.

      Returns:
      the random source, non-null
    • initializeRandom

      private void initializeRandom()
      Creates the secure random source.
    • addShutdownTask

      public void addShutdownTask(Runnable task)
      WARNING - Shutdown tasks are not executed in an I2PAppContext. You must be in a RouterContext for the tasks to be executed at shutdown. This method moved from Router in 0.7.1 so that clients may use it without depending on router.jar.
      Parameters:
      task - the Runnable to invoke during shutdown
    • removeShutdownTask

      public void removeShutdownTask(Runnable task)
      Remove a shutdown task.
      Parameters:
      task - the previously added Runnable to drop from the shutdown set
    • getShutdownTasks

      public Set<Runnable> getShutdownTasks()
      List of shutdown tasks.
      Returns:
      an unmodifiable Set of shutdown tasks
    • isRouterContext

      public boolean isRouterContext()
      Use this instead of context instanceof RouterContext.
      Returns:
      false always in I2PAppContext
    • internalClientManager

      public InternalClientManager internalClientManager()
      Use this to connect to the router in the same JVM.
      Returns:
      always null in I2PAppContext, the client manager if in RouterContext
    • hasWrapper

      public boolean hasWrapper()
      Is the wrapper present?
      Returns:
      true if the wrapper is present
    • portMapper

      public PortMapper portMapper()
      Basic mapping from service names to ports.
      Returns:
      the port mapper
    • simpleTimer2

      public SimpleTimer2 simpleTimer2()
      Returns:
      the SimpleTimer2 instance
    • initializeSimpleTimer2

      private void initializeSimpleTimer2()
      Creates the shared timer.
    • clientAppManager

      public ClientAppManager clientAppManager()
      The ClientAppManager for this context, non-null in a standalone context and null in a router context. RouterContext overrides this to return the RouterAppManager.
      Returns:
      the app manager, null in a router context
    • getEstimatedDowntime

      public long getEstimatedDowntime()
      How long this router was down before it started, or 0 if unknown.

      This may be used for a determination of whether to regenerate keys, for example. We use the timestamp of the previous ping file left behind on crash, as set by isOnlyRouterRunning(), if present. Otherwise, the last STOPPED entry in the event log.

      May take a while to run the first time, if it has to go through the event log. Once called, the result is cached.

      Returns:
      0 always in app context