Bug 441254: test disposed realms are forgotten

Change-Id: Ie9301fd43fbb664ef5dcc56df22d0761a7057693
Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
diff --git a/org.eclipse.sisu.plexus.tests/resources/component-jar/component-jar-0.1.jar b/org.eclipse.sisu.plexus.tests/resources/component-jar/component-jar-0.1.jar
new file mode 100644
index 0000000..3c4e9dd
--- /dev/null
+++ b/org.eclipse.sisu.plexus.tests/resources/component-jar/component-jar-0.1.jar
Binary files differ
diff --git a/org.eclipse.sisu.plexus.tests/resources/component-jar/pom.xml b/org.eclipse.sisu.plexus.tests/resources/component-jar/pom.xml
new file mode 100644
index 0000000..ce05685
--- /dev/null
+++ b/org.eclipse.sisu.plexus.tests/resources/component-jar/pom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2014 Takari, Inc.
+ ~ All rights reserved. This program and the accompanying materials
+ ~ are made available under the terms of the Eclipse Public License v1.0
+ ~ which accompanies this distribution, and is available at
+ ~ http://www.eclipse.org/legal/epl-v10.html
+ ~
+ ~ Contributors:
+ ~    Takari, Inc. - initial API and implementation
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.eclipse.sisu.plexus.tests</groupId>
+  <artifactId>component-jar</artifactId>
+  <version>0.1</version>
+
+</project>
diff --git a/org.eclipse.sisu.plexus.tests/resources/component-jar/src/main/java/org/eclipse/sisu/plexus/tests/SomeComponent.java b/org.eclipse.sisu.plexus.tests/resources/component-jar/src/main/java/org/eclipse/sisu/plexus/tests/SomeComponent.java
new file mode 100644
index 0000000..295638f
--- /dev/null
+++ b/org.eclipse.sisu.plexus.tests/resources/component-jar/src/main/java/org/eclipse/sisu/plexus/tests/SomeComponent.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Takari, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Takari, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sisu.plexus.tests;
+
+public class SomeComponent
+{
+
+}
diff --git a/org.eclipse.sisu.plexus.tests/resources/component-jar/src/main/resources/META-INF/plexus/components.xml b/org.eclipse.sisu.plexus.tests/resources/component-jar/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 0000000..320cd3c
--- /dev/null
+++ b/org.eclipse.sisu.plexus.tests/resources/component-jar/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2014 Takari, Inc.
+ ~ All rights reserved. This program and the accompanying materials
+ ~ are made available under the terms of the Eclipse Public License v1.0
+ ~ which accompanies this distribution, and is available at
+ ~ http://www.eclipse.org/legal/epl-v10.html
+ ~
+ ~ Contributors:
+ ~    Takari, Inc. - initial API and implementation
+-->
+<component-set>
+  <components>
+    <component>
+      <role>org.eclipse.sisu.plexus.tests.SomeComponent</role>
+      <role-hint>default</role-hint>
+      <implementation>org.eclipse.sisu.plexus.tests.SomeComponent</implementation>
+      <description />
+      <isolated-realm>false</isolated-realm>
+    </component>
+  </components>
+</component-set>
diff --git a/org.eclipse.sisu.plexus.tests/src/org/eclipse/sisu/plexus/DefaultPlexusContainerTest.java b/org.eclipse.sisu.plexus.tests/src/org/eclipse/sisu/plexus/DefaultPlexusContainerTest.java
new file mode 100644
index 0000000..1cafb28
--- /dev/null
+++ b/org.eclipse.sisu.plexus.tests/src/org/eclipse/sisu/plexus/DefaultPlexusContainerTest.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Takari, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Takari, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sisu.plexus;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.codehaus.plexus.DefaultPlexusContainer;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+
+public class DefaultPlexusContainerTest
+    extends TestCase
+{
+    private ClassLoader origCL;
+
+    @Override
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+        origCL = Thread.currentThread().getContextClassLoader();
+    }
+
+    @Override
+    protected void tearDown()
+        throws Exception
+    {
+        Thread.currentThread().setContextClassLoader( origCL );
+        super.tearDown();
+    }
+
+    public void test441254_recreateChildRealm()
+        throws Exception
+    {
+        String realmId = "child-realm";
+
+        DefaultPlexusContainer plexus = new DefaultPlexusContainer();
+
+        ClassRealm realm = plexus.createChildRealm( realmId );
+        realm.addURL( new File( "resources/component-jar/component-jar-0.1.jar" ).getCanonicalFile().toURI().toURL() );
+        Thread.currentThread().setContextClassLoader( realm );
+        plexus.discoverComponents( realm );
+        assertNotNull( plexus.lookup( "org.eclipse.sisu.plexus.tests.SomeComponent" ) );
+
+        realm.getWorld().disposeRealm( realm.getId() );
+
+        realm = plexus.createChildRealm( realmId );
+        realm.addURL( new File( "resources/component-jar/component-jar-0.1.jar" ).getCanonicalFile().toURI().toURL() );
+        Thread.currentThread().setContextClassLoader( realm );
+        plexus.discoverComponents( realm );
+        assertNotNull( plexus.lookup( "org.eclipse.sisu.plexus.tests.SomeComponent" ) );
+    }
+
+    // the point of this disabled test is to manually assert all references to the disposed realms are cleared
+    // the test runs create/dispose the same realm 100k times and prints 1k iterations how long it took
+    // each 1k are expected to take about the same time to execute (as opposed to always increasing time)
+    // it is recommended to run the test with -Xmx128m to make sure there are no memory leaks
+    public void _test441254_torture()
+        throws Exception
+    {
+        String realmId = "child-realm";
+
+        DefaultPlexusContainer plexus = new DefaultPlexusContainer();
+
+        ClassRealm realm = plexus.createChildRealm( realmId );
+        realm.addURL( new File( "resources/component-jar/component-jar-0.1.jar" ).getCanonicalFile().toURI().toURL() );
+        Thread.currentThread().setContextClassLoader( realm );
+        plexus.discoverComponents( realm );
+
+        long start = System.currentTimeMillis();
+        for ( int i = 0; i < 100000; i++ )
+        {
+            realm.getWorld().disposeRealm( realm.getId() );
+
+            realm = plexus.createChildRealm( realmId );
+            realm.addURL( new File( "resources/component-jar/component-jar-0.1.jar" ).getCanonicalFile().toURI().toURL() );
+            Thread.currentThread().setContextClassLoader( realm );
+            plexus.discoverComponents( realm );
+
+            if ( i % 1000 == 0 )
+            {
+                long end = System.currentTimeMillis();
+                System.out.printf( "%6d %d\n", i, end - start );
+                start = end;
+            }
+        }
+
+        realm.getWorld().disposeRealm( realm.getId() );
+
+        System.in.read();
+    }
+
+}