[JavaWorker] Java code lint check and binding to CI (#2225)

* add java code lint check and fix the java code lint error

* add java doc lint check and fix the java doc lint error

* add java code and doc lint to the CI
This commit is contained in:
Yujie Liu
2018-06-10 07:26:54 +08:00
committed by Philipp Moritz
parent 5789a247f9
commit 3b5e700fd7
158 changed files with 3805 additions and 3325 deletions
+75 -75
View File
@@ -1,88 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.ray.parent</groupId>
<artifactId>ray-superpom</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.ray.parent</groupId>
<artifactId>ray-superpom</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.ray</groupId>
<artifactId>ray-hook</artifactId>
<name>java api hook for ray</name>
<description>java api hook for ray</description>
<url></url>
<groupId>org.ray</groupId>
<artifactId>ray-hook</artifactId>
<name>java api hook for ray</name>
<description>java api hook for ray</description>
<url></url>
<packaging>jar</packaging>
<packaging>jar</packaging>
<dependencies>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-common</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-common</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifestEntries>
<Premain-Class>org.ray.hook.Agent</Premain-Class>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifestEntries>
<Premain-Class>org.ray.hook.Agent</Premain-Class>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.objectweb.asm</pattern>
<shadedPattern>agent.org.objectweb.asm</shadedPattern>
</relocation>
</relocations>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.objectweb.asm</pattern>
<shadedPattern>agent.org.objectweb.asm</shadedPattern>
</relocation>
</relocations>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -6,21 +6,10 @@ import org.objectweb.asm.ClassWriter;
public class ClassAdapter {
public static class Result {
public byte[] classBuffer;
public Set<MethodId> changedMethods;
}
public static Result hookClass(ClassLoader loader, String className, byte[] classfileBuffer) {
// we have to comment out this quick filter as this is not accurate
// e.g., org/ray/api/test/ActorTest$Adder.class is skipped!!!
// even worse, this is non-deterministic...
/*
if (detectBody.contains("org/ray/hook/")) {
return classfileBuffer;
}
*/
ClassReader reader = new ClassReader(classfileBuffer);
ClassWriter writer = new ClassWriter(reader, 0);
@@ -46,4 +35,10 @@ public class ClassAdapter {
rr.classBuffer = result;
return rr;
}
public static class Result {
public byte[] classBuffer;
public Set<MethodId> changedMethods;
}
}
@@ -11,20 +11,16 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
/**
* rewrite phase 1
* rewrite phase 1.
*/
public class ClassDetectVisitor extends ClassVisitor {
static int count = 0;
final String className;
final Set<MethodId> rayMethods = new HashSet<>();
boolean isActor = false;
static int count = 0;
int actorCalls = 0;
final ClassLoader loader;
public int actorCalls() {
return actorCalls;
}
boolean isActor = false;
int actorCalls = 0;
public ClassDetectVisitor(ClassLoader loader, ClassVisitor origin, String className) {
super(Opcodes.ASM6, origin);
@@ -32,15 +28,12 @@ public class ClassDetectVisitor extends ClassVisitor {
this.loader = loader;
}
public Set<MethodId> detectedMethods() {
return rayMethods;
public int actorCalls() {
return actorCalls;
}
@Override
public void visitInnerClass(String name, String outerName,
String innerName, int access) {
// System.err.println("visist inner class " + outerName + "$" + innerName);
super.visitInnerClass(name, outerName, innerName, access);
public Set<MethodId> detectedMethods() {
return rayMethods;
}
@Override
@@ -51,20 +44,16 @@ public class ClassDetectVisitor extends ClassVisitor {
return super.visitAnnotation(desc, visible);
}
private void visitRayMethod(int access, String name, String mdesc) {
if (name.equals("<init>")) {
return;
}
MethodId m = new MethodId(className, name, mdesc, (access & Opcodes.ACC_STATIC) != 0, loader);
rayMethods.add(m);
//System.err.println("Visit " + m.toString());
count++;
@Override
public void visitInnerClass(String name, String outerName,
String innerName, int access) {
// System.err.println("visist inner class " + outerName + "$" + innerName);
super.visitInnerClass(name, outerName, innerName, access);
}
@Override
public MethodVisitor visitMethod(int access, String name, String mdesc, String signature,
String[] exceptions) {
String[] exceptions) {
//System.out.println("Visit " + className + "." + name);
if (isActor && (access & Opcodes.ACC_PUBLIC) != 0) {
visitRayMethod(access, name, mdesc);
@@ -81,41 +70,9 @@ public class ClassDetectVisitor extends ClassVisitor {
return super.visitAnnotation(adesc, visible);
}
private boolean isValidCallParameterOrReturnType(Type t) {
if (t.equals(Type.VOID_TYPE)) {
return false;
}
if (t.equals(Type.BOOLEAN_TYPE)) {
return false;
}
if (t.equals(Type.CHAR_TYPE)) {
return false;
}
if (t.equals(Type.BYTE_TYPE)) {
return false;
}
if (t.equals(Type.SHORT_TYPE)) {
return false;
}
if (t.equals(Type.INT_TYPE)) {
return false;
}
if (t.equals(Type.FLOAT_TYPE)) {
return false;
}
if (t.equals(Type.LONG_TYPE)) {
return false;
}
if (t.equals(Type.DOUBLE_TYPE)) {
return false;
}
return true;
}
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
Object... bsmArgs) {
// fix all actor calls from InvokeVirtual to InvokeStatic
if (desc.contains("org/ray/api/funcs/RayFunc_")) {
@@ -151,7 +108,8 @@ public class ClassDetectVisitor extends ClassVisitor {
dsptr,
h.isInterface());
bsmArgs[i] = newh;
//System.err.println("Change ray.call from " + h + " -> " + newh + ", isInterface = " + h.isInterface());
//System.err.println("Change ray.call from " + h + " -> " + newh + ", isInterface
// = " + h.isInterface());
++actorCalls;
}
}
@@ -159,6 +117,49 @@ public class ClassDetectVisitor extends ClassVisitor {
}
super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
}
private boolean isValidCallParameterOrReturnType(Type t) {
if (t.equals(Type.VOID_TYPE)) {
return false;
}
if (t.equals(Type.BOOLEAN_TYPE)) {
return false;
}
if (t.equals(Type.CHAR_TYPE)) {
return false;
}
if (t.equals(Type.BYTE_TYPE)) {
return false;
}
if (t.equals(Type.SHORT_TYPE)) {
return false;
}
if (t.equals(Type.INT_TYPE)) {
return false;
}
if (t.equals(Type.FLOAT_TYPE)) {
return false;
}
if (t.equals(Type.LONG_TYPE)) {
return false;
}
if (t.equals(Type.DOUBLE_TYPE)) {
return false;
}
return true;
}
};
}
private void visitRayMethod(int access, String name, String mdesc) {
if (name.equals("<init>")) {
return;
}
MethodId m = new MethodId(className, name, mdesc, (access & Opcodes.ACC_STATIC) != 0, loader);
rayMethods.add(m);
//System.err.println("Visit " + m.toString());
count++;
}
}
@@ -7,75 +7,33 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* rewrite phase 2
* rewrite phase 2.
*/
public class ClassOverrideVisitor extends ClassVisitor {
final String className;
final Set<MethodId> rayRemoteMethods;
MethodVisitor ClinitVisitor;
// init the static added field in <clinit>
// static {
// assign value to _hashOf_XXX
// }
class StaticBlockVisitor extends MethodVisitor {
StaticBlockVisitor(MethodVisitor mv) {
super(Opcodes.ASM6, mv);
}
@Override
public void visitCode() {
super.visitCode();
// assign value for added hash fields within <clinit>
for (MethodId m : rayRemoteMethods) {
byte[] hash = m.getSha1Hash();
insertByteArray(hash);
mv.visitFieldInsn(Opcodes.PUTSTATIC, className, m.getStaticHashValueFieldName(), "[B");
System.out.println("assign field: " + m.getStaticHashValueFieldName() + " = " + MethodId
.toHexHashString(hash));
}
}
private void insertByteArray(byte[] bytes) {
int length = bytes.length;
assert (length < Short.MAX_VALUE);
mv.visitIntInsn(Opcodes.SIPUSH, length);
mv.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_BYTE);
mv.visitInsn(Opcodes.DUP);
for (int i = 0; i < length; ++i) {
mv.visitIntInsn(Opcodes.BIPUSH, i);
mv.visitIntInsn(Opcodes.BIPUSH, bytes[i]);
mv.visitInsn(Opcodes.BASTORE);
if (i < (length - 1)) {
mv.visitInsn(Opcodes.DUP);
}
}
}
}
MethodVisitor clinitVisitor;
public ClassOverrideVisitor(ClassVisitor origin, String className,
Set<MethodId> rayRemoteMethods) {
Set<MethodId> rayRemoteMethods) {
super(Opcodes.ASM6, origin);
this.className = className;
this.rayRemoteMethods = rayRemoteMethods;
this.ClinitVisitor = null;
this.clinitVisitor = null;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature,
String[] exceptions) {
if ("<clinit>".equals(name) && ClinitVisitor == null) {
String[] exceptions) {
if ("<clinit>".equals(name) && clinitVisitor == null) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
ClinitVisitor = new StaticBlockVisitor(mv);
return ClinitVisitor;// dispatch the ASM modifications (assign values to the preComputedxxx static field) to the ClinitVisitor
clinitVisitor = new StaticBlockVisitor(mv);
return clinitVisitor;// dispatch the ASM modifications (assign values to the preComputedxxx
// static field) to the clinitVisitor
}
ClassVisitor this_ = this;
ClassVisitor current = this;
MethodId m = new MethodId(className, name, desc, (access & Opcodes.ACC_STATIC) != 0, null);
if (rayRemoteMethods.contains(m)) {
if (m.isStaticMethod()) {
@@ -86,10 +44,11 @@ public class ClassOverrideVisitor extends ClassVisitor {
// step 1: add a field for the function id of this method
System.out.println("add field: " + m.getStaticHashValueFieldName());
String fieldName = m.getStaticHashValueFieldName();
this_.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, fieldName, "[B",
current.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, fieldName, "[B",
null, null);
// step 2: rewrite current method so if MethodSwitcher returns true, returns the added function id directly
// step 2: rewrite current method so if MethodSwitcher returns true, returns the
// added function id directly
// else call the original method
mv.visitFieldInsn(Opcodes.GETSTATIC, className, fieldName, "[B");
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/ray/hook/runtime/MethodSwitcher",
@@ -103,10 +62,7 @@ public class ClassOverrideVisitor extends ClassVisitor {
mv.visitCode();// real work
}
};
}
// non-static
else {
} else { // non-static
return super.visitMethod(access, name, desc, signature, exceptions);
}
} else {
@@ -116,7 +72,7 @@ public class ClassOverrideVisitor extends ClassVisitor {
@Override
public void visitEnd() {
if (ClinitVisitor == null) { // works fine
if (clinitVisitor == null) { // works fine
// Create an empty static block and let our method
// visitor modify it the same way it modifies an
// existing static block
@@ -163,14 +119,6 @@ public class ClassOverrideVisitor extends ClassVisitor {
org.objectweb.asm.Type[] args = org.objectweb.asm.Type
.getArgumentTypes(mid.getIdMethodDesc());
int argCount = args.length;
/*
for (int i = 0; i < argCount; ++i) {
String ldsptr = args[i].getDescriptor();
if (!ldsptr.endsWith(";"))
ldsptr = "L" + ldsptr + ";";
mv.visitLocalVariable("arg" + i, ldsptr, null, l0, l2, i);
}
*/
mv.visitMaxs(2, argCount);
mv.visitEnd();
}
@@ -220,4 +168,47 @@ public class ClassOverrideVisitor extends ClassVisitor {
return str.substring(left);
}
// init the static added field in <clinit>
// static {
// assign value to _hashOf_XXX
// }
class StaticBlockVisitor extends MethodVisitor {
StaticBlockVisitor(MethodVisitor mv) {
super(Opcodes.ASM6, mv);
}
@Override
public void visitCode() {
super.visitCode();
// assign value for added hash fields within <clinit>
for (MethodId m : rayRemoteMethods) {
byte[] hash = m.getSha1Hash();
insertByteArray(hash);
mv.visitFieldInsn(Opcodes.PUTSTATIC, className, m.getStaticHashValueFieldName(), "[B");
System.out.println("assign field: " + m.getStaticHashValueFieldName() + " = " + MethodId
.toHexHashString(hash));
}
}
private void insertByteArray(byte[] bytes) {
int length = bytes.length;
assert (length < Short.MAX_VALUE);
mv.visitIntInsn(Opcodes.SIPUSH, length);
mv.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_BYTE);
mv.visitInsn(Opcodes.DUP);
for (int i = 0; i < length; ++i) {
mv.visitIntInsn(Opcodes.BIPUSH, i);
mv.visitIntInsn(Opcodes.BIPUSH, bytes[i]);
mv.visitInsn(Opcodes.BASTORE);
if (i < (length - 1)) {
mv.visitInsn(Opcodes.DUP);
}
}
}
}
}
@@ -6,7 +6,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
@@ -26,7 +25,7 @@ import org.ray.hook.runtime.LoadedFunctions;
import org.ray.util.logger.RayLog;
/**
* rewrite jars to new jars with methods marked using Ray annotations
* rewrite jars to new jars with methods marked using Ray annotations.
*/
public class JarRewriter {
@@ -51,10 +50,32 @@ public class JarRewriter {
rewrite(args[0], args[1]);
}
public static LoadedFunctions load(String dir, String baseDir)
throws FileNotFoundException, SecurityException {
List<String> functions = JarRewriter.getRewrittenFunctions(dir);
LoadedFunctions efuncs = new LoadedFunctions();
efuncs.loader = JarLoader.loadJars(dir, false);
for (String func : functions) {
MethodId mid = new MethodId(func, efuncs.loader);
efuncs.functions.add(mid);
}
if (baseDir != null && !baseDir.equals("")) {
List<String> baseFunctions = JarRewriter.getRewrittenFunctions(baseDir);
for (String func : baseFunctions) {
MethodId mid = new MethodId(func, efuncs.loader);
efuncs.functions.add(mid);
}
}
return efuncs;
}
public static void rewrite(String fromDir, String toDir) throws IOException, DataFormatException {
File fromDirFile = new File(fromDir);
File toDirFileTmp = new File(toDir + ".tmp");
File toDirFile = new File(toDir);
final File toDirFile = new File(toDir);
File[] topFiles = fromDirFile.listFiles();
if (topFiles.length != 1 || !topFiles[0].isDirectory()) {
@@ -103,57 +124,6 @@ public class JarRewriter {
FileUtils.moveDirectory(toDirFileTmp, toDirFile);
}
public static LoadedFunctions load(String dir, String baseDir)
throws FileNotFoundException, SecurityException {
List<String> functions = JarRewriter.getRewrittenFunctions(dir);
LoadedFunctions efuncs = new LoadedFunctions();
efuncs.loader = JarLoader.loadJars(dir, false);
for (String func : functions) {
MethodId mid = new MethodId(func, efuncs.loader);
efuncs.functions.add(mid);
}
if (baseDir != null && !baseDir.equals("")) {
List<String> baseFunctions = JarRewriter.getRewrittenFunctions(baseDir);
for (String func : baseFunctions) {
MethodId mid = new MethodId(func, efuncs.loader);
efuncs.functions.add(mid);
}
}
return efuncs;
}
public static LoadedFunctions loadBase(String baseDir)
throws FileNotFoundException, SecurityException {
List<String> functions = JarRewriter.getRewrittenFunctions(baseDir);
LoadedFunctions efuncs = new LoadedFunctions();
efuncs.loader = null;
for (String func : functions) {
MethodId mid = new MethodId(func, efuncs.loader);
efuncs.functions.add(mid);
}
return efuncs;
}
public static List<String> getRewrittenFunctions(String rewrittenDir)
throws FileNotFoundException {
ArrayList<String> functions = new ArrayList<>();
Scanner s = new Scanner(new File(rewrittenDir + "/" + FUNCTIONS_FILE));
while (s.hasNext()) {
String f = s.next();
if (!f.startsWith("(")) {
functions.add(f);
}
}
s.close();
return functions;
}
public static void rewrite(JarFile from, String to, BiConsumer<ClassLoader, MethodId> consumer)
throws IOException {
@@ -170,7 +140,8 @@ public class JarRewriter {
if (!je.isDirectory() && je.getName().endsWith(".class")) {
className = je.getName().substring(0, je.getName().length() - ".class".length());
//System.err.println("XXXXXX " + from.getName() + " :: " + je.getName() + " - " + className);
//System.err.println("XXXXXX " + from.getName() + " :: " + je.getName() + " - " +
// className);
ClassAdapter.Result result = ClassAdapter.hookClass(null, className, jeBytes);
if (result.classBuffer != jeBytes) {
String logInfo = "Rewrite class " + className + " from " + jeBytes.length + " bytes to "
@@ -198,4 +169,33 @@ public class JarRewriter {
ojStream.close();
ofStream.close();
}
public static List<String> getRewrittenFunctions(String rewrittenDir)
throws FileNotFoundException {
ArrayList<String> functions = new ArrayList<>();
Scanner s = new Scanner(new File(rewrittenDir + "/" + FUNCTIONS_FILE));
while (s.hasNext()) {
String f = s.next();
if (!f.startsWith("(")) {
functions.add(f);
}
}
s.close();
return functions;
}
public static LoadedFunctions loadBase(String baseDir)
throws FileNotFoundException, SecurityException {
List<String> functions = JarRewriter.getRewrittenFunctions(baseDir);
LoadedFunctions efuncs = new LoadedFunctions();
efuncs.loader = null;
for (String func : functions) {
MethodId mid = new MethodId(func, efuncs.loader);
efuncs.functions.add(mid);
}
return efuncs;
}
}
@@ -11,27 +11,26 @@ import org.objectweb.asm.Type;
import org.ray.util.logger.RayLog;
/**
* Represent a Method in a Class
* Represent a Method in a Class.
*/
public class MethodId {
static final String getFunctionIdPostfix = "_function_id";
String className;
String methodName;
String methodDesc;
boolean isStatic;
ClassLoader loader;
static final String getFunctionIdPostfix = "_function_id";
public MethodId(String cls, String method, String mdesc, boolean isstatic, ClassLoader loader_) {
public MethodId(String cls, String method, String mdesc, boolean isstatic, ClassLoader loader) {
className = cls;
methodName = method;
methodDesc = mdesc;
isStatic = isstatic;
loader = loader_;
this.loader = loader;
}
public MethodId(String encodedString, ClassLoader loader_) {
public MethodId(String encodedString, ClassLoader loader) {
// className + "." + methodName + "::" + methodDesc + "&&" + isStatic;
int lastPos3 = encodedString.lastIndexOf("&&");
int lastPos2 = encodedString.lastIndexOf("::");
@@ -45,7 +44,24 @@ public class MethodId {
methodName = encodedString.substring(lastPos1 + ".".length(), lastPos2);
methodDesc = encodedString.substring(lastPos2 + "::".length(), lastPos3);
isStatic = Boolean.parseBoolean(encodedString.substring(lastPos3 + "&&".length()));
loader = loader_;
this.loader = loader;
}
public static String toHexHashString(byte[] id) {
String s = "";
String hex = "0123456789abcdef";
assert (id.length == 20);
for (int i = 0; i < 20; i++) {
int val = id[i] & 0xff;
s += hex.charAt(val >> 4);
s += hex.charAt(val & 0xf);
}
return s;
}
private String toHexHashString() {
byte[] id = this.getSha1Hash();
return toHexHashString(id);
}
public String getClassName() {
@@ -76,23 +92,6 @@ public class MethodId {
return "(L" + this.className + ";" + this.methodDesc.substring(1);
}
public static String toHexHashString(byte[] id) {
String s = "";
String hex = "0123456789abcdef";
assert (id.length == 20);
for (int i = 0; i < 20; i++) {
int val = id[i] & 0xff;
s += hex.charAt(val >> 4);
s += hex.charAt(val & 0xf);
}
return s;
}
private String toHexHashString() {
byte[] id = this.getSha1Hash();
return toHexHashString(id);
}
public Method load() {
String loadClsName = className.replace('/', '.');
Class<?> cls;
@@ -153,7 +152,8 @@ public class MethodId {
: "<nil>") + " vs id-hash: " + toHexHashString());
}
}
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException
| IllegalAccessException e) {
RayLog.core.error("load method hash field failed for " + toString(), e);
}
return m;
@@ -17,13 +17,13 @@ import org.apache.commons.io.filefilter.RegexFileFilter;
import org.ray.util.logger.RayLog;
/**
* load and unload jars from a dir
* load and unload jars from a dir.
*/
public class JarLoader {
private static Method AddUrl = InitAddUrl();
private static Method AddUrl = initAddUrl();
private static Method InitAddUrl() {
private static Method initAddUrl() {
try {
Method m = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
m.setAccessible(true);
@@ -59,10 +59,6 @@ public class JarLoader {
return loadJar(jars, explicitLoadForHook);
}
public static void unloadJars(ClassLoader loader) {
// TODO:
}
private static URLClassLoader loadJar(Collection<File> appJars, boolean explicitLoadForHook) {
List<JarFile> jars = new ArrayList<>();
List<URL> urls = new ArrayList<>();
@@ -128,4 +124,8 @@ public class JarLoader {
jars.addAll(files);
}
public static void unloadJars(ClassLoader loader) {
// TODO:
}
}
@@ -7,6 +7,6 @@ import org.ray.hook.MethodId;
public class LoadedFunctions {
public ClassLoader loader = null;
public final Set<MethodId> functions = Collections.synchronizedSet(new HashSet<>());
public ClassLoader loader = null;
}
@@ -10,15 +10,15 @@ public class MethodHash {
this.hash = hash;
}
public byte[] getHash() {
return hash;
}
@Override
public int hashCode() {
return Arrays.hashCode(getHash());
}
public byte[] getHash() {
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
@@ -1,7 +1,7 @@
package org.ray.hook.runtime;
/**
* method mode switch at runtime
* method mode switch at runtime.
*/
public class MethodSwitcher {