use of org.hotswap.agent.javassist.CtMethod 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.javassist.CtMethod in project HotswapAgent by HotswapProjects.
the class TransformCall method matchClass.
private boolean matchClass(String name, ClassPool pool) {
if (classname.equals(name))
return true;
try {
CtClass clazz = pool.get(name);
CtClass declClazz = pool.get(classname);
if (clazz.subtypeOf(declClazz))
try {
CtMethod m = clazz.getMethod(methodname, methodDescriptor);
return m.getDeclaringClass().getName().equals(classname);
} catch (NotFoundException e) {
// maybe the original method has been removed.
return true;
}
} catch (NotFoundException e) {
return false;
}
return false;
}
use of org.hotswap.agent.javassist.CtMethod in project HotswapAgent by HotswapProjects.
the class CtClassSignature method getValue.
@Override
public String getValue() throws Exception {
List<String> strings = new ArrayList<>();
if (hasElement(ClassSignatureElement.METHOD)) {
boolean usePrivateMethod = hasElement(ClassSignatureElement.METHOD_PRIVATE);
boolean useStaticMethod = hasElement(ClassSignatureElement.METHOD_STATIC);
for (CtMethod method : ctClass.getDeclaredMethods()) {
if (!usePrivateMethod && Modifier.isPrivate(method.getModifiers()))
continue;
if (!useStaticMethod && Modifier.isStatic(method.getModifiers()))
continue;
strings.add(getMethodString(method));
}
}
if (hasElement(ClassSignatureElement.CONSTRUCTOR)) {
boolean usePrivateConstructor = hasElement(ClassSignatureElement.CONSTRUCTOR_PRIVATE);
for (CtConstructor method : ctClass.getDeclaredConstructors()) {
if (!usePrivateConstructor && Modifier.isPrivate(method.getModifiers()))
continue;
strings.add(getConstructorString(method));
}
}
if (hasElement(ClassSignatureElement.CLASS_ANNOTATION)) {
strings.add(annotationToString(ctClass.getAvailableAnnotations()));
}
if (hasElement(ClassSignatureElement.INTERFACES)) {
for (CtClass iClass : ctClass.getInterfaces()) {
strings.add(iClass.getName());
}
}
if (hasElement(ClassSignatureElement.SUPER_CLASS)) {
if (ctClass.getSuperclass() != null && !ctClass.getSuperclass().getName().equals(Object.class.getName()))
strings.add(ctClass.getSuperclass().getName());
}
if (hasElement(ClassSignatureElement.FIELD)) {
boolean useStaticField = hasElement(ClassSignatureElement.FIELD_STATIC);
boolean useFieldAnnotation = hasElement(ClassSignatureElement.FIELD_ANNOTATION);
for (CtField field : ctClass.getDeclaredFields()) {
if (!useStaticField && Modifier.isStatic(field.getModifiers()))
continue;
String fieldSignature = field.getType().getName() + " " + field.getName();
if (useFieldAnnotation) {
fieldSignature += annotationToString(field.getAvailableAnnotations());
}
strings.add(fieldSignature + ";");
}
}
Collections.sort(strings);
StringBuilder strBuilder = new StringBuilder();
for (String methodString : strings) {
strBuilder.append(methodString);
}
return strBuilder.toString();
}
use of org.hotswap.agent.javassist.CtMethod in project HotswapAgent by HotswapProjects.
the class ResteasyPlugin method patchFilterDispatcher.
@OnClassLoadEvent(classNameRegexp = "org.jboss.resteasy.plugins.server.servlet.FilterDispatcher")
public static void patchFilterDispatcher(CtClass ctClass, ClassPool classPool) throws NotFoundException, CannotCompileException {
CtClass fltCfgClass = classPool.get("javax.servlet.FilterConfig");
CtField configField = new CtField(fltCfgClass, FIELD_NAME, ctClass);
ctClass.addField(configField);
CtClass setClass = classPool.get(java.util.Set.class.getName());
CtField paramsField = new CtField(setClass, PARAMETER_FIELD_NAME, ctClass);
ctClass.addField(paramsField);
CtMethod methInit = ctClass.getDeclaredMethod("init");
methInit.insertBefore("{" + " if(this." + PARAMETER_FIELD_NAME + " == null) {" + PluginManagerInvoker.buildInitializePlugin(ResteasyPlugin.class) + PluginManagerInvoker.buildCallPluginMethod(ResteasyPlugin.class, "registerDispatcher", "this", "java.lang.Object") + " }" + " this." + FIELD_NAME + " = $1;" + " this." + PARAMETER_FIELD_NAME + " = " + ResteasyContextParams.class.getName() + ".init($1.getServletContext(), this." + PARAMETER_FIELD_NAME + "); " + "}");
}
use of org.hotswap.agent.javassist.CtMethod in project HotswapAgent by HotswapProjects.
the class ResteasyPlugin method patchServletDispatcher.
@OnClassLoadEvent(classNameRegexp = "org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher")
public static void patchServletDispatcher(CtClass ctClass, ClassPool classPool) throws NotFoundException, CannotCompileException {
CtClass fltCfgClass = classPool.get("javax.servlet.ServletConfig");
CtField configField = new CtField(fltCfgClass, FIELD_NAME, ctClass);
ctClass.addField(configField);
CtClass setClass = classPool.get(java.util.Set.class.getName());
CtField paramsField = new CtField(setClass, PARAMETER_FIELD_NAME, ctClass);
ctClass.addField(paramsField);
CtMethod methInit = ctClass.getDeclaredMethod("init");
methInit.insertBefore("{" + " if(this." + PARAMETER_FIELD_NAME + " == null) {" + PluginManagerInvoker.buildInitializePlugin(ResteasyPlugin.class) + PluginManagerInvoker.buildCallPluginMethod(ResteasyPlugin.class, "registerDispatcher", "this", "java.lang.Object") + " }" + " this." + FIELD_NAME + " = $1;" + " this." + PARAMETER_FIELD_NAME + " = " + ResteasyContextParams.class.getName() + ".init($1.getServletContext(), this." + PARAMETER_FIELD_NAME + "); " + "}");
}
Aggregations