Bug 570660: [RJ-Servi] Fix regular shutdown of pool (was prevented by
nodes created after closing process is started)

Change-Id: I03efa6749bbd3a153896bb1400b5e26e8f842b2d
diff --git a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/JMPoolTest.java b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/JMPoolTest.java
index c7cf739..b615bef 100644
--- a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/JMPoolTest.java
+++ b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/JMPoolTest.java
@@ -290,6 +290,24 @@
 		closeServi(servi2);
 	}
 	
+	
+	@Test
+	public void Bug570660() throws Exception {
+		final ProgressMonitor m= new NullProgressMonitor();
+		
+		final PoolConfig poolConfig= new PoolConfig();
+		poolConfig.setMaxTotalCount(2);
+		poolConfig.setMinIdleCount(2);
+		this.server.setPoolConfig(poolConfig);
+		this.server.start();
+		
+		final RServi servi1= getServi("test1");
+		assertNodeOperative(servi1);
+		
+		closeServi(servi1);
+	}
+	
+	
 	private void assertIdleCount(final int expected) throws InterruptedException {
 		final long t= System.nanoTime();
 		while (true) {
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2.java
index cec2485..3b33f4d 100644
--- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2.java
+++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2.java
@@ -69,6 +69,8 @@
 	}
 	
 	
+	private final String id;
+	
 	private final APool2NodeFactory factory;
 	
 	private volatile byte state;
@@ -76,18 +78,32 @@
 	private final Object stateLock= new Object();
 	
 	
-	public APool2(final APool2NodeFactory factory, final PoolConfig config) {
+	public APool2(final String id, final APool2NodeFactory factory, final PoolConfig config) {
 		super(factory, createAConfig(config));
+		this.id= id;
 		
 		factory.setPool(this);
 		this.factory= factory;
 	}
 	
 	
+	public String getId() {
+		return this.id;
+	}
+	
+	
 	public void setConfig(final PoolConfig config) {
 		setConfig(createAConfig(config));
 	}
 	
+	@Override
+	public int getMaxIdle() {
+		if (this.state != 0) {
+			return 0;
+		}
+		return super.getMaxIdle();
+	}
+	
 	
 	public APool2NodeHandler borrowObject(final String client) throws Exception {
 		if (this.state != 0) {
@@ -103,15 +119,12 @@
 		}
 	}
 	
-	@Override
-	public int getMinIdle() {
-		if (this.state != 0) {
-			return 0;
-		}
-		return super.getMinIdle();
-	}
 	
 	
+	public boolean isOpen() {
+		return (this.state == 0);
+	}
+	
 	@Override
 	public void close() {
 		throw new UnsupportedOperationException();
@@ -124,6 +137,9 @@
 			}
 			this.state= CLOSING;
 		}
+		final long evictNanos= APool2NodeHandler.evictNanos(evictionTimeout);
+		final boolean evictDirect= (evictionTimeout == 0);
+		
 		try {
 			Thread.sleep(10);
 		}
@@ -131,9 +147,6 @@
 		
 		clear();
 		
-		final long evictNanos= APool2NodeHandler.evictNanos(evictionTimeout);
-		final boolean evictDirect= (evictionTimeout == 0);
-		
 		final ImList<APool2NodeHandler> objects= this.factory.getAllObjects();
 		for (final APool2NodeHandler poolObj : objects) {
 			poolObj.doEvict(evictNanos, evictDirect);
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeFactory.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeFactory.java
index ede7ab1..b8ac23b 100644
--- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeFactory.java
+++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeFactory.java
@@ -17,6 +17,8 @@
 import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
 import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
 
+import static org.eclipse.statet.rj.servi.RServiUtils.RJ_SERVI_ID;
+
 import java.rmi.server.RMIClientSocketFactory;
 import java.rmi.server.RMIServerSocketFactory;
 import java.rmi.server.RemoteServer;
@@ -39,7 +41,6 @@
 import org.eclipse.statet.jcommons.runtime.CommonsRuntime;
 import org.eclipse.statet.jcommons.status.ErrorStatus;
 
-import org.eclipse.statet.rj.servi.RServiUtils;
 import org.eclipse.statet.rj.servi.node.RServiNode;
 
 
@@ -109,6 +110,10 @@
 		
 		boolean ok= false;
 		try {
+			if (!this.pool.isOpen()) {
+				throw new IllegalStateException("Pool not open");
+			}
+			
 			for (final PoolListener listener : this.poolListeners.toList()) {
 				try {
 					listener.initializing(poolObj);
@@ -150,7 +155,7 @@
 		}
 		finally {
 			if (!ok) {
-				this.nodes.remove(poolObj);
+				destroyObject(poolObj.getPooledObject());
 			}
 		}
 	}
@@ -261,9 +266,9 @@
 	
 	
 	private void onErrorInListener(final PoolListener listener, final Exception e) {
-		CommonsRuntime.log(new ErrorStatus(RServiUtils.RJ_SERVI_ID,
-				String.format("An error occurred in pool listener (%1$s).",
-						listener.getClass().getSimpleName() ),
+		CommonsRuntime.log(new ErrorStatus(RJ_SERVI_ID,
+				String.format("An error occurred in pool listener (%1$s) of '%2$s'.",
+						listener.getClass().getSimpleName(), this.pool.getId() ),
 				e ));
 	}
 	
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/PoolManager.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/PoolManager.java
index 492e78d..af0579c 100644
--- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/PoolManager.java
+++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/PoolManager.java
@@ -112,7 +112,7 @@
 	@Override
 	public synchronized void setConfig(final PoolConfig config) {
 		final var pool= this.pool;
-		if (pool != null) {
+		if (pool != null && pool.isOpen()) {
 			final var poolFactory= nonNullAssert(this.poolFactory);
 			pool.setConfig(config);
 			poolFactory.setMaxUsageCount(config.getMaxUsageCount());
@@ -139,7 +139,7 @@
 				this.nodeFactories.get(0), this.poolListeners, this.executor );
 		poolFactory.setMaxUsageCount(this.poolConfig.getMaxUsageCount());
 		this.poolFactory= poolFactory;
-		final var pool= new APool2(poolFactory, this.poolConfig) {
+		final var pool= new APool2(this.id, poolFactory, this.poolConfig) {
 			@Override
 			protected void closeFinally() {
 				super.closeFinally();