diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
index 76ba3c847b3e0c8a7ed73c6503ef6f85e752674e..d284c6a30d45291bd007188581380466ad40adfd 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
@@ -201,7 +201,7 @@ public class ConfigServiceHandler extends FormHandler {
      */
     public boolean shouldShowSystray() {
         return !
-            (RouterConsoleRunner.DAEMON_USER.equals(System.getProperty("user.name")) ||
+            (SystemVersion.isLinuxService() ||
              (SystemVersion.isWindows() && _context.hasWrapper() && WrapperManager.isLaunchedAsService()) ||
              // headless=true is forced in i2prouter script to prevent useless dock icon;
              // must fix this first
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
index 38153fb756ba71ce7ce34f3fa5489ea9d0ecbdfa..5440aa4c6028c901de66144c0ee6614e6dda9a01 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
@@ -131,7 +131,6 @@ public class RouterConsoleRunner implements RouterApp {
     private static final int MAX_THREADS = 24;
     private static final int MAX_IDLE_TIME = 90*1000;
     private static final String THREAD_NAME = "RouterConsole Jetty";
-    public static final String DAEMON_USER = "i2psvc";
     public static final String PROP_DTG_ENABLED = "desktopgui.enabled";
     
     /**
@@ -273,7 +272,7 @@ public class RouterConsoleRunner implements RouterApp {
     private void startTrayApp() {
         // if no permissions, don't even try
         // isLaunchedAsService() always returns true on Linux
-        if (DAEMON_USER.equals(System.getProperty("user.name")) ||
+        if (SystemVersion.isLinuxService() ||
             (SystemVersion.isWindows() && _context.hasWrapper() && WrapperManager.isLaunchedAsService())) {
             // required true for jrobin to work
             System.setProperty("java.awt.headless", "true");
diff --git a/core/java/src/net/i2p/util/SystemVersion.java b/core/java/src/net/i2p/util/SystemVersion.java
index a24759098a0a7db803417cbdc3816a6c109b7ba5..f8f6a1c5d680f9a3fa320e106e74bd593b79a0e4 100644
--- a/core/java/src/net/i2p/util/SystemVersion.java
+++ b/core/java/src/net/i2p/util/SystemVersion.java
@@ -16,6 +16,11 @@ import net.i2p.I2PAppContext;
  */
 public abstract class SystemVersion {
 
+    /*
+     *  @since 0.9.28
+     */
+    public static final String DAEMON_USER = "i2psvc";
+
     private static final boolean _isWin = System.getProperty("os.name").startsWith("Win");
     private static final boolean _isMac = System.getProperty("os.name").startsWith("Mac");
     private static final boolean _isArm = System.getProperty("os.arch").startsWith("arm");
@@ -29,6 +34,8 @@ public abstract class SystemVersion {
     private static final boolean _isOpenJDK;
     private static final boolean _is64;
     private static final boolean _hasWrapper = System.getProperty("wrapper.version") != null;
+    private static final boolean _isLinuxService = !_isWin && !_isMac &&
+                                                   DAEMON_USER.equals(System.getProperty("user.name"));
 
     private static final boolean _oneDotSix;
     private static final boolean _oneDotSeven;
@@ -193,6 +200,13 @@ public abstract class SystemVersion {
         return _is64;
     }
 
+    /*
+     *  @since 0.9.28
+     */
+    public static boolean isLinuxService() {
+        return _isLinuxService;
+    }
+
     /**
      *  Identical to android.os.Build.VERSION.SDK_INT.
      *  For use outside of Android code.
@@ -268,6 +282,7 @@ public abstract class SystemVersion {
         System.out.println("Mac      : " + isMac());
         System.out.println("Gentoo   : " + isGentoo());
         System.out.println("GNU      : " + isGNU());
+        System.out.println("Linux Svc: " + isLinuxService());
         System.out.println("OpenJDK  : " + isOpenJDK());
         System.out.println("Windows  : " + isWindows());
         System.out.println("Wrapper  : " + hasWrapper());
diff --git a/router/java/src/net/i2p/router/startup/WorkingDir.java b/router/java/src/net/i2p/router/startup/WorkingDir.java
index a7ca9f3303045343be4e4c5c4db3fd0f9406c61a..4a9a0e4a3653566e4c3928babd976eef6ac8c06e 100644
--- a/router/java/src/net/i2p/router/startup/WorkingDir.java
+++ b/router/java/src/net/i2p/router/startup/WorkingDir.java
@@ -53,7 +53,6 @@ public class WorkingDir {
     private final static String WORKING_DIR_DEFAULT = ".i2p";
     private final static String WORKING_DIR_DEFAULT_DAEMON = "i2p-config";
     /** we do a couple of things differently if this is the username */
-    private final static String DAEMON_USER = "i2psvc";
     private static final String PROP_WRAPPER_LOG = "wrapper.logfile";
     private static final String DEFAULT_WRAPPER_LOG = "wrapper.log";
     /** Feb 16 2006 */
@@ -93,7 +92,7 @@ public class WorkingDir {
                     dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_MAC);
                 }
             } else {
-                if (DAEMON_USER.equals(System.getProperty("user.name")))
+                if (SystemVersion.isLinuxService())
                     dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_DAEMON);
                 else
                     dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT);
@@ -306,7 +305,7 @@ public class WorkingDir {
             out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(newFile), "UTF-8")));
             out.println("# Modified by I2P User dir migration script");
             String s = null;
-            boolean isDaemon = DAEMON_USER.equals(System.getProperty("user.name"));
+            boolean isDaemon = SystemVersion.isLinuxService();
             while ((s = DataHelper.readLine(in)) != null) {
                 // readLine() doesn't strip \r
                 if (s.endsWith("\r"))
diff --git a/router/java/src/net/i2p/router/tasks/OOMListener.java b/router/java/src/net/i2p/router/tasks/OOMListener.java
index 7f09f677dc9fdb7aea721ea863d46774d0174df5..3aa2c08661367d714d5888b8b314f66dbc47e5e6 100644
--- a/router/java/src/net/i2p/router/tasks/OOMListener.java
+++ b/router/java/src/net/i2p/router/tasks/OOMListener.java
@@ -53,8 +53,7 @@ public class OOMListener implements I2PThread.OOMEventListener {
                 // Can't find any System property or wrapper property that gives
                 // you the actual config file path, have to guess
                 String path;
-                if (!SystemVersion.isWindows() && !SystemVersion.isMac() &&
-                    "i2psvc".equals(System.getProperty("user.name"))) {
+                if (SystemVersion.isLinuxService()) {
                     path = "/etc/i2p";
                 } else {
                     path = _context.getBaseDir().toString();
diff --git a/router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java b/router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java
index 62fa46231a0049e0525cb627f90679643b32ea95..f96bdfece26e5622b063151fc24323fb402cd8f4 100644
--- a/router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java
+++ b/router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java
@@ -106,8 +106,7 @@ class BloomFilterIVValidator implements IVValidator {
         // you the actual config file path, have to guess
         // TODO if !SystemVersion.hasWrapper ...
         String path;
-        if (!SystemVersion.isWindows() && !SystemVersion.isMac() &&
-            "i2psvc".equals(System.getProperty("user.name"))) {
+        if (SystemVersion.isLinuxService()) {
             path = "/etc/i2p";
         } else {
             path = _context.getBaseDir().toString();