Repository: karaf
Updated Branches:
  refs/heads/master 6af8d60e5 -> 70112462a


KARAF-3460 Complete fix for threading issue


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/70112462
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/70112462
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/70112462

Branch: refs/heads/master
Commit: 70112462a6c87eb770237357e6b4fe4b3cd6ef9d
Parents: 6af8d60
Author: Christian Schneider <[email protected]>
Authored: Thu Jan 22 12:10:54 2015 +0100
Committer: Christian Schneider <[email protected]>
Committed: Thu Jan 22 12:10:54 2015 +0100

----------------------------------------------------------------------
 jaas/modules/pom.xml                            |  1 +
 .../karaf/jaas/modules/impl/Activator.java      |  8 +-
 .../properties/AutoEncryptionSupport.java       | 92 ++++++++++----------
 3 files changed, 49 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/70112462/jaas/modules/pom.xml
----------------------------------------------------------------------
diff --git a/jaas/modules/pom.xml b/jaas/modules/pom.xml
index 2c6d01c..2d5c181 100644
--- a/jaas/modules/pom.xml
+++ b/jaas/modules/pom.xml
@@ -158,6 +158,7 @@
                         <Private-Package>
                             org.apache.karaf.jaas.modules.impl,
                             org.apache.felix.utils.properties,
+                            org.apache.karaf.util,
                             org.apache.karaf.util.tracker,
                             org.apache.http*,
                             org.apache.commons.codec*

http://git-wip-us.apache.org/repos/asf/karaf/blob/70112462/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/impl/Activator.java
----------------------------------------------------------------------
diff --git 
a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/impl/Activator.java 
b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/impl/Activator.java
index 4532692..cd190fa 100644
--- 
a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/impl/Activator.java
+++ 
b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/impl/Activator.java
@@ -26,6 +26,7 @@ import org.apache.karaf.jaas.modules.ldap.LDAPCache;
 import org.apache.karaf.jaas.modules.properties.AutoEncryptionSupport;
 import org.apache.karaf.jaas.modules.properties.PropertiesBackingEngineFactory;
 import org.apache.karaf.jaas.modules.publickey.PublickeyBackingEngineFactory;
+import org.apache.karaf.util.StreamUtils;
 import org.apache.karaf.util.tracker.BaseActivator;
 import org.apache.karaf.util.tracker.Managed;
 import org.apache.karaf.util.tracker.ProvideService;
@@ -76,9 +77,7 @@ public class Activator extends BaseActivator implements 
ManagedService {
 
     @Override
     protected void doStop() {
-        if (autoEncryptionSupport != null) {
-            autoEncryptionSupport.destroy();
-        }
+        StreamUtils.close(autoEncryptionSupport);
         super.doStop();
         LDAPCache.clear();
     }
@@ -90,8 +89,9 @@ public class Activator extends BaseActivator implements 
ManagedService {
             karafRealm.updated(config);
         }
         if (autoEncryptionSupport != null) {
-            autoEncryptionSupport.updated(config);
+            StreamUtils.close(autoEncryptionSupport);
         }
+        autoEncryptionSupport = new AutoEncryptionSupport(config);
     }
 
     private Map<String, Object> getConfig() {

http://git-wip-us.apache.org/repos/asf/karaf/blob/70112462/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/AutoEncryptionSupport.java
----------------------------------------------------------------------
diff --git 
a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/AutoEncryptionSupport.java
 
b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/AutoEncryptionSupport.java
index 06714af..9fc1a53 100644
--- 
a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/AutoEncryptionSupport.java
+++ 
b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/AutoEncryptionSupport.java
@@ -16,8 +16,10 @@
  */
 package org.apache.karaf.jaas.modules.properties;
 
+import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
+
+import java.io.Closeable;
 import java.io.IOException;
-import java.nio.file.ClosedWatchServiceException;
 import java.nio.file.FileSystems;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -25,87 +27,81 @@ import java.nio.file.WatchEvent;
 import java.nio.file.WatchKey;
 import java.nio.file.WatchService;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.felix.utils.properties.Properties;
 import org.apache.karaf.jaas.modules.Encryption;
 import org.apache.karaf.jaas.modules.encryption.EncryptionSupport;
+import org.apache.karaf.util.StreamUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
-
-public class AutoEncryptionSupport implements Runnable {
+public class AutoEncryptionSupport implements Runnable, Closeable {
 
     private final Logger LOGGER = 
LoggerFactory.getLogger(AutoEncryptionSupport.class);
-
-    private WatchService watchService;
-
+    boolean running;
     private volatile EncryptionSupport encryptionSupport;
+    private ExecutorService executor;
 
     public AutoEncryptionSupport(Map<String, Object> properties) {
-        updated(properties);
-    }
-
-    public synchronized void init() {
-        try {
-            watchService = FileSystems.getDefault().newWatchService();
-            new Thread(this, "AutoEncryptionSupport").start();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
+        running = true;
+        this.encryptionSupport = new EncryptionSupport(properties);
+        executor = Executors.newSingleThreadExecutor();
+        executor.execute(this);
     }
 
-    public synchronized void destroy() {
+    public void close() {
+        running = false;
+        executor.shutdown();
         try {
-            if (watchService != null) {
-                watchService.close();
-                watchService = null;
-            }
-        } catch (IOException e) {
+            executor.awaitTermination(10, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
             // Ignore
         }
     }
 
-    public void updated(Map<String, Object> properties) {
-        destroy();
-        this.encryptionSupport = new EncryptionSupport(properties);
-        init();
-    }
-
     @Override
     public void run() {
+        WatchService watchService = null;
         try {
+            watchService = FileSystems.getDefault().newWatchService();
             Path dir = Paths.get(System.getProperty("karaf.etc"));
-            if (watchService == null) {
-                // just to prevent NPE (KARAF-3460)
-                watchService = FileSystems.getDefault().newWatchService();
-            }
             dir.register(watchService, ENTRY_MODIFY);
 
             Path file = dir.resolve("users.properties");
             encryptedPassword(new Properties(file.toFile()));
 
-            while (true) {
-                WatchKey key = watchService.take();
-                for (WatchEvent<?> event : key.pollEvents()) {
-                    WatchEvent.Kind kind = event.kind();
-                    WatchEvent<Path> ev = (WatchEvent<Path>) event;
-
-                    // Context for directory entry event is the file name of 
entry
-                    Path name = dir.resolve(ev.context());
-                    if (file.equals(name)) {
-                        encryptedPassword(new Properties(file.toFile()));
+            while (running) {
+                try {
+                    WatchKey key = watchService.poll(1, TimeUnit.SECONDS);
+                    if (key == null) {
+                        continue;
                     }
+                    for (WatchEvent<?> event : key.pollEvents()) {
+                        @SuppressWarnings("unchecked")
+                        WatchEvent<Path> ev = (WatchEvent<Path>)event;
+
+                        // Context for directory entry event is the file name 
of entry
+                        Path name = dir.resolve(ev.context());
+                        if (file.equals(name)) {
+                            encryptedPassword(new Properties(file.toFile()));
+                        }
+                    }
+                    key.reset();
+                } catch (IOException e) {
+                    LOGGER.warn(e.getMessage(), e);
+                } catch (InterruptedException e) {
+                    // Ignore as this happens on shutdown
                 }
-                key.reset();
             }
 
-        } catch (ClosedWatchServiceException | InterruptedException e) {
-            // Ignore
         } catch (IOException e) {
-            LOGGER.warn("Unable to encrypt user properties file ", e);
+            LOGGER.warn(e.getMessage(), e);
+        } finally {
+            StreamUtils.close(watchService);
         }
-
     }
 
     void encryptedPassword(Properties users) throws IOException {

Reply via email to