-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
194 additions
and
108 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
src/main/java/net/bluedash/snippets/classloader/MultiThreadProductFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package net.bluedash.snippets.classloader; | ||
|
||
import org.jboss.netty.handler.codec.serialization.WeakReferenceMap; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Proxy; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* Created with IntelliJ IDEA. | ||
* User: weli | ||
* Date: 5/24/13 | ||
* Time: 7:28 PM | ||
* To change this template use File | Settings | File Templates. | ||
*/ | ||
public class MultiThreadProductFactory extends ProductFactory { | ||
static protected WeakReferenceMap<Long, Proxy> productProxies; // in multi-thread environment, we need to store each threads' proxy independently. | ||
|
||
public static Product newInstance() throws InstantiationException, | ||
IllegalAccessException { | ||
return newInstance(ProductImpl.class);// default implementation | ||
} | ||
|
||
public static Product newInstance(Class clazz) throws InstantiationException, | ||
IllegalAccessException { | ||
Product product = (Product) clazz.newInstance(); // default implementation | ||
Product productProxy = ProductInvocationHandler.newInstance(product); | ||
productProxies.put(Long.valueOf(Thread.currentThread().getId()), (Proxy) productProxy); | ||
return productProxy; | ||
} | ||
|
||
public static void reload(String productClassPath) throws ClassNotFoundException, | ||
InstantiationException, IllegalAccessException, | ||
NoSuchMethodException, InvocationTargetException { | ||
cl = new SimpleClassLoader(PREFIX + productClassPath); | ||
String binaryName = productClassPath.replace('/', '.') + ".ProductImpl"; | ||
Class productImplClass = cl.loadClass(binaryName); | ||
|
||
Proxy productProxy = productProxies.get(Thread.currentThread().getId()); | ||
|
||
if (productProxy != null) { | ||
ProductInvocationHandler productInvocationHandler = (ProductInvocationHandler) Proxy.getInvocationHandler(productProxy); | ||
Product replacement = (Product) productImplClass.newInstance(); | ||
productInvocationHandler.setProductInstance(replacement); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
package net.bluedash.snippets.classloader; | ||
|
||
public interface Product { | ||
public void show(); | ||
public String getName(); | ||
} |
47 changes: 18 additions & 29 deletions
47
src/main/java/net/bluedash/snippets/classloader/ProductFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,35 @@ | ||
package net.bluedash.snippets.classloader; | ||
|
||
import java.lang.ref.WeakReference; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Proxy; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class ProductFactory { | ||
static private ClassLoader cl = null; | ||
static private Class implClass = ProductImpl.class; // default class | ||
static private List instances = new ArrayList(); | ||
static protected ClassLoader cl = null; | ||
static protected Object productProxy; // we store this because we want to get invocation handler from proxy later | ||
|
||
public static Product newInstance() throws InstantiationException, | ||
IllegalAccessException { | ||
Product obj = (Product) implClass.newInstance(); | ||
Product anAProxy = (Product) ProductIH.newInstance(obj); | ||
instances.add(new WeakReference(anAProxy)); | ||
return anAProxy; | ||
Product product = ProductImpl.class.newInstance(); // default implementation | ||
Product productProxy = ProductInvocationHandler.newInstance(product); | ||
ProductFactory.productProxy = productProxy; | ||
return productProxy; | ||
} | ||
|
||
private static final String PREFIX = "target/classes/"; | ||
protected static final String PREFIX = "target/classes/"; | ||
|
||
public static void reload(String dir) throws ClassNotFoundException, | ||
public static void reload(String productClassPath) throws ClassNotFoundException, | ||
InstantiationException, IllegalAccessException, | ||
NoSuchMethodException, InvocationTargetException { | ||
cl = new SimpleClassLoader(PREFIX + dir); | ||
String binaryName = dir.replace('/', '.') + ".ProductImpl"; | ||
implClass = cl.loadClass(binaryName); | ||
|
||
List newInstances = new ArrayList(); | ||
|
||
for (int i = 0; i < instances.size(); i++) { | ||
Proxy x = (Proxy) ((WeakReference) instances.get(i)).get(); | ||
if (x != null) { | ||
ProductIH aih = (ProductIH) Proxy.getInvocationHandler(x); | ||
Object oldObject = aih.getTarget(); | ||
Object replacement = implClass.newInstance(); | ||
aih.setTarget(replacement); | ||
newInstances.add(new WeakReference(x)); | ||
} | ||
cl = new SimpleClassLoader(PREFIX + productClassPath); | ||
String binaryName = productClassPath.replace('/', '.') + ".ProductImpl"; | ||
Class productImplClass = cl.loadClass(binaryName); | ||
|
||
Proxy productProxy = (Proxy) ProductFactory.productProxy; | ||
if (productProxy != null) { | ||
ProductInvocationHandler productInvocationHandler = (ProductInvocationHandler) Proxy.getInvocationHandler(productProxy); | ||
Product replacement = (Product) productImplClass.newInstance(); | ||
productInvocationHandler.setProductInstance(replacement); | ||
ProductFactory.productProxy = productProxy; | ||
} | ||
|
||
instances = newInstances; | ||
} | ||
} |
40 changes: 0 additions & 40 deletions
40
src/main/java/net/bluedash/snippets/classloader/ProductIH.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/main/java/net/bluedash/snippets/classloader/ProductInvocationHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package net.bluedash.snippets.classloader; | ||
|
||
import java.lang.reflect.InvocationHandler; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.lang.reflect.Proxy; | ||
|
||
class ProductInvocationHandler implements InvocationHandler { | ||
private Object productInstance = null; | ||
static private Class[] productInterface = { Product.class }; | ||
|
||
public static Product newInstance(Product productInstance) { | ||
return (Product) Proxy.newProxyInstance( | ||
productInstance.getClass().getClassLoader(), productInterface, | ||
new ProductInvocationHandler(productInstance)); | ||
} | ||
|
||
private ProductInvocationHandler(Object productInstance) { | ||
this.productInstance = productInstance; | ||
} | ||
|
||
public void setProductInstance(Object productInstance) { | ||
this.productInstance = productInstance; | ||
} | ||
|
||
public Object getProductInstance() { | ||
return productInstance; | ||
} | ||
|
||
public Object invoke(Object t, Method m, Object[] args) throws Throwable { | ||
Object result; | ||
try { | ||
Method _m = productInstance.getClass().getMethod(m.getName()); | ||
result = _m.invoke(productInstance); | ||
} catch (InvocationTargetException e) { | ||
throw e.getTargetException(); | ||
} | ||
return result; | ||
} | ||
} |
19 changes: 0 additions & 19 deletions
19
src/main/java/net/bluedash/snippets/classloader/ProductReloadTest.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/main/java/net/bluedash/snippets/classloader/impl2/impl3/ProductImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package net.bluedash.snippets.classloader.impl2.impl3; | ||
|
||
import net.bluedash.snippets.classloader.Product; | ||
|
||
/** | ||
* Created with IntelliJ IDEA. | ||
* User: weli | ||
* Date: 5/24/13 | ||
* Time: 7:33 PM | ||
* To change this template use File | Settings | File Templates. | ||
*/ | ||
public class ProductImpl implements Product { | ||
|
||
public String getName() { | ||
return "ProductImpl3"; | ||
|
||
} | ||
|
||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/net/bluedash/snippets/log4j/PlayWithLog4j.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package net.bluedash.snippets.log4j; | ||
|
||
/** | ||
* Created with IntelliJ IDEA. | ||
* User: weli | ||
* Date: 5/24/13 | ||
* Time: 4:46 PM | ||
* To change this template use File | Settings | File Templates. | ||
*/ | ||
public class PlayWithLog4j { | ||
} |
Empty file.
19 changes: 19 additions & 0 deletions
19
src/test/java/net/bluedash/snippets/classloader/ProductReloadTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package net.bluedash.snippets.classloader; | ||
|
||
|
||
import junit.framework.Assert; | ||
import org.junit.Test; | ||
|
||
public class ProductReloadTest { | ||
|
||
@Test | ||
public void testProductFactory() throws Exception { | ||
Product product = ProductFactory.newInstance(); | ||
Assert.assertEquals("ProductImpl", product.getName()); | ||
|
||
ProductFactory.reload("net/bluedash/snippets/classloader/impl2"); | ||
/* the product is replaced by a new instance */ | ||
Assert.assertEquals("ProductImpl2", product.getName()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters