use of org.hotswap.agent.command.Command in project HotswapAgent by HotswapProjects.
the class ClassInitPlugin method patch.
@OnClassLoadEvent(classNameRegexp = ".*", events = LoadEvent.REDEFINE)
public static void patch(final CtClass ctClass, final ClassLoader classLoader, final Class<?> originalClass) throws IOException, CannotCompileException, NotFoundException {
if (isSyntheticClass(originalClass)) {
return;
}
final String className = ctClass.getName();
try {
CtMethod origMethod = ctClass.getDeclaredMethod(HOTSWAP_AGENT_CLINIT_METHOD);
ctClass.removeMethod(origMethod);
} catch (org.hotswap.agent.javassist.NotFoundException ex) {
// swallow
}
CtConstructor clinit = ctClass.getClassInitializer();
if (clinit != null) {
LOGGER.debug("Adding __ha_clinit to class: {}", className);
CtConstructor haClinit = new CtConstructor(clinit, ctClass, null);
haClinit.getMethodInfo().setName(HOTSWAP_AGENT_CLINIT_METHOD);
haClinit.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
ctClass.addConstructor(haClinit);
final boolean[] reinitializeStatics = new boolean[] { false };
haClinit.instrument(new ExprEditor() {
public void edit(FieldAccess f) throws CannotCompileException {
try {
if (f.isStatic() && f.isWriter()) {
Field originalField = null;
try {
originalField = originalClass.getDeclaredField(f.getFieldName());
} catch (NoSuchFieldException e) {
LOGGER.debug("New field will be initialized {}", f.getFieldName());
reinitializeStatics[0] = true;
}
if (originalField != null) {
// ENUM$VALUES is last in enumeration
if (originalClass.isEnum() && "ENUM$VALUES".equals(f.getFieldName())) {
if (reinitializeStatics[0]) {
LOGGER.debug("New field will be initialized {}", f.getFieldName());
} else {
reinitializeStatics[0] = checkOldEnumValues(ctClass, originalClass);
}
} else {
LOGGER.debug("Skipping old field {}", f.getFieldName());
f.replace("{}");
}
}
}
} catch (Exception e) {
LOGGER.error("Patching __ha_clinit method failed.", e);
}
}
});
if (reinitializeStatics[0]) {
PluginManager.getInstance().getScheduler().scheduleCommand(new Command() {
@Override
public void executeCommand() {
try {
Class<?> clazz = classLoader.loadClass(className);
Method m = clazz.getDeclaredMethod(HOTSWAP_AGENT_CLINIT_METHOD, new Class[] {});
if (m != null) {
m.invoke(null, new Object[] {});
}
} catch (Exception e) {
LOGGER.error("Error initializing redefined class {}", e, className);
} finally {
reloadFlag = false;
}
}
}, // Hack : init should be done after dependant class redefinition. Since the class can
150);
// be proxied by syntetic proxy, the class init must be scheduled after proxy redefinition.
// Currently proxy redefinition (in ProxyPlugin) is scheduled with 100ms delay, therefore
// the class init must be scheduled after it.
} else {
reloadFlag = false;
}
}
}
use of org.hotswap.agent.command.Command in project HotswapAgent by HotswapProjects.
the class ResteasyPlugin method refresh.
private void refresh(ClassLoader classLoader, int timeout) {
if (!registeredDispatchers.isEmpty()) {
try {
Class<?> cmdClass = Class.forName(RefreshDispatchersCommand.class.getName(), true, appClassLoader);
Command cmd = (Command) cmdClass.newInstance();
ReflectionHelper.invoke(cmd, cmdClass, "setupCmd", new Class[] { java.lang.ClassLoader.class, java.util.Set.class }, classLoader, registeredDispatchers);
scheduler.scheduleCommand(cmd, timeout);
} catch (Exception e) {
LOGGER.error("refresh() exception {}.", e.getMessage());
}
}
}
use of org.hotswap.agent.command.Command in project HotswapAgent by HotswapProjects.
the class ResteasyRegistryPlugin method refreshClass.
private void refreshClass(ClassLoader classLoader, String name, Class<?> original, int timeout) {
try {
Class<?> cmdClass = Class.forName(RefreshRegistryCommand.class.getName(), true, appClassLoader);
Command cmd = (Command) cmdClass.newInstance();
ReflectionHelper.invoke(cmd, cmdClass, "setupCmd", new Class[] { ClassLoader.class, Object.class, Object.class, String.class, java.lang.Class.class }, classLoader, servletContext, servletContainerDispatcher, name, original);
scheduler.scheduleCommand(cmd, timeout);
} catch (Exception e) {
LOGGER.error("refreshClass() exception {}.", e.getMessage());
}
}
use of org.hotswap.agent.command.Command in project HotswapAgent by HotswapProjects.
the class BeanClassRefreshCommand method isDeleteEvent.
/**
* Check all merged events with same className for delete and create events. If delete without create is found, than assume
* file was deleted.
* @param mergedCommands
*/
private boolean isDeleteEvent(List<Command> mergedCommands) {
boolean createFound = false;
boolean deleteFound = false;
for (Command cmd : mergedCommands) {
BeanClassRefreshCommand refreshCommand = (BeanClassRefreshCommand) cmd;
if (className.equals(refreshCommand.className)) {
if (refreshCommand.event != null) {
if (refreshCommand.event.getEventType().equals(FileEvent.DELETE))
deleteFound = true;
if (refreshCommand.event.getEventType().equals(FileEvent.CREATE))
createFound = true;
}
}
}
LOGGER.trace("isDeleteEvent result {}: createFound={}, deleteFound={}", createFound, deleteFound);
return !createFound && deleteFound;
}
use of org.hotswap.agent.command.Command in project HotswapAgent by HotswapProjects.
the class ReloadJavaProxyCommand method executeCommand.
public void executeCommand() {
try {
executeSingleCommand();
List<Command> commands = new ArrayList<>(getMergedCommands());
for (Command command : commands) {
((ReloadJavaProxyCommand) command).executeSingleCommand();
}
} finally {
ProxyPlugin.reloadFlag = false;
}
}
Aggregations