0

There is a class com.mycompany.MyBadClass in my Java classpath.

I'm trying to instrument the JVM with a javaagent to swap MyBadClass for MyGoodClass, which is also in the classpath.

public static class BugFixAgent {
  public static void premain(String args, Instrumentation inst) {
    inst.addClassFileTransformer(new ClassFileTransformer() {
      @Override
      public byte[] transform(ClassLoader loader, 
                              String className, 
                              Class<?> classBeingRedefined, 
                              ProtectionDomain protectionDomain, 
                              byte[] classfileBuffer) {
        if (className.equals("com/mycompany/MyBadClass")) {
          return patchedClassAsByteArray; // <====== ??????
        } else {
          return null; // skips instrumentation for other classes
        }
      }
    });
  }
}

So my question is: How do I load a byte array of com.mycompany.MyGoodClass from the classpath programmatically?

LatencyFighter
  • 351
  • 2
  • 11
  • Does your "good" class have a different name or a different package-structure than the class you try to replace? If so, I'm not sure if simply loading the bytes of the other class will fix the issue. Furthermore, was your "bad" class loaded before by the application class loader or a classloader you try to load the patched version with? If so, you might get the class definition of "bad" class on each lookup unless you break the classloader delegation rules and therefore violate the overall contract. – Roman Vottner Feb 06 '18 at 18:09

2 Answers2

2

You can get an InputStream with

loader.getResourceAsStream(name + ".class");

Which can then be converted to a byte array.

henry
  • 5,923
  • 29
  • 46
0

You basically want to

  • first scan your classpath ( see here for ideas )
  • you basically stop when you "found" MyGoodClass - and ideally the result of the scan process is some sort of handle that allows you to access the file belonging to the class

If your class path just contains directory names, that is pretty easy - but maybe your class sits in some JAR, and then some more work is required.

But as said: the core thing is the initial "scan". That is a (somewhat) solved problem, it only requires "work" to get done.

GhostCat
  • 137,827
  • 25
  • 176
  • 248