Skip to content

Instantly share code, notes, and snippets.

@ilgrosso
Created July 16, 2018 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilgrosso/c12fa371a5033de1e92b0a35115b6456 to your computer and use it in GitHub Desktop.
Save ilgrosso/c12fa371a5033de1e92b0a35115b6456 to your computer and use it in GitHub Desktop.
Hotswap: tentative Wicket plugin
import java.lang.reflect.Method;
import org.hotswap.agent.annotation.Init;
import org.hotswap.agent.annotation.OnClassLoadEvent;
import org.hotswap.agent.annotation.OnResourceFileEvent;
import org.hotswap.agent.annotation.Plugin;
import org.hotswap.agent.command.Scheduler;
import org.hotswap.agent.javassist.CannotCompileException;
import org.hotswap.agent.javassist.CtClass;
import org.hotswap.agent.javassist.NotFoundException;
import org.hotswap.agent.logging.AgentLogger;
import org.hotswap.agent.util.PluginManagerInvoker;
import org.hotswap.agent.command.Command;
@Plugin(name = "Wicket",
description = "Apache Wicket. Clear resource bundle cache when *.properties files are changed.",
testedVersions = { "7.10.0", "8.0.0" }
)
public class WicketPlugin {
private static final AgentLogger LOG = AgentLogger.getLogger(WicketPlugin.class);
@Init
private Scheduler scheduler;
@Init
private ClassLoader appClassLoader;
private final Command clearCache = new Command() {
@Override
public void executeCommand() {
LOG.debug("Refreshing Wicket resource bundles.");
try {
Class<?> clazz = Class.forName("java.util.ResourceBundle", true, appClassLoader);
Method clearCacheMethod = clazz.getDeclaredMethod("clearCache", ClassLoader.class);
clearCacheMethod.invoke(null, appClassLoader);
clearCacheMethod = Class.forName("org.apache.wicket.Localizer", true, appClassLoader).
getDeclaredMethod("clearCache");
clearCacheMethod.invoke(getLocalizer());
} catch (Exception e) {
LOG.error("Error clear Wicket resource bundles cache", e);
}
}
};
private Object wicketApplication;
@OnClassLoadEvent(classNameRegexp = "org.apache.wicket.protocol.http.WebApplication")
public static void init(final CtClass ctClass) throws NotFoundException, CannotCompileException {
String src = PluginManagerInvoker.buildInitializePlugin(WicketPlugin.class);
src += PluginManagerInvoker.buildCallPluginMethod(WicketPlugin.class,
"registerApplication", "this", "java.lang.Object");
ctClass.getDeclaredConstructor(new CtClass[0]).insertAfter(src);
LOG.info("Initialized Wicket plugin");
}
public void registerApplication(final Object wicketApplication) {
this.wicketApplication = wicketApplication;
LOG.info("Plugin {} initialized for application {}", getClass(), wicketApplication);
}
@OnResourceFileEvent(path = "/", filter = ".*.properties")
public void clearLocalizerCaches() {
scheduler.scheduleCommand(clearCache);
}
private Object getLocalizer() {
try {
Method getResourceSettingsMethod =
Class.forName("org.apache.wicket.Application", true, appClassLoader).
getDeclaredMethod("getResourceSettings");
Method getLocalizerMethod =
Class.forName("org.apache.wicket.settings.ResourceSettings", true, appClassLoader).
getDeclaredMethod("getLocalizer");
return getLocalizerMethod.invoke(getResourceSettingsMethod.invoke(wicketApplication));
} catch (Exception e) {
LOG.error("Error getting Wicket localizer", e);
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment