org.yx.asm.AsmUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sumk Show documentation
Show all versions of sumk Show documentation
A quick developing framewort for internet company
/**
* Copyright (C) 2016 - 2030 youtongluan.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.yx.asm;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.yx.bean.Loader;
import org.yx.conf.AppInfo;
import org.yx.exception.SumkException;
import org.yx.log.Log;
import org.yx.log.Logs;
import org.yx.main.StartContext;
public final class AsmUtils {
private static final ConcurrentHashMap> clzMap = new ConcurrentHashMap<>();
private static Method defineClass;
static {
try {
defineClass = getMethod(ClassLoader.class, "defineClass",
new Class>[] { String.class, byte[].class, int.class, int.class });
defineClass.setAccessible(true);
} catch (Exception e) {
Log.printStack("sumk.error", e);
StartContext.startFailed();
}
}
public static String proxyCalssName(Class> clz) {
String name = clz.getName();
int index = name.lastIndexOf('.');
return name.substring(0, index) + ".sumkbox" + name.substring(index);
}
public static int asmVersion() {
return AppInfo.getInt("sumk.asm.version", Opcodes.ASM7);
}
public static int jvmVersion() {
return AppInfo.getInt("sumk.asm.jvm.version", Opcodes.V1_8);
}
public static InputStream openStreamForClass(String name) {
String internalName = name.replace('.', '/') + ".class";
return Loader.getResourceAsStream(internalName);
}
public static boolean sameType(Type[] types, Class>[] clazzes) {
if (types.length != clazzes.length) {
return false;
}
for (int i = 0; i < types.length; i++) {
if (!Type.getType(clazzes[i]).equals(types[i])) {
return false;
}
}
return true;
}
public static List buildMethodInfos(List methods) throws IOException {
Map, List> map = new HashMap<>();
for (Method m : methods) {
List list = map.get(m.getDeclaringClass());
if (list == null) {
list = new ArrayList<>();
map.put(m.getDeclaringClass(), list);
}
list.add(m);
}
List ret = new ArrayList<>();
for (List ms : map.values()) {
ret.addAll(buildMethodInfos(ms.get(0).getDeclaringClass(), ms));
}
return ret;
}
private static List buildMethodInfos(Class> declaringClass, List methods)
throws IOException {
String classFullName = declaringClass.getName();
ClassReader cr = new ClassReader(openStreamForClass(classFullName));
MethodInfoClassVisitor cv = new MethodInfoClassVisitor(methods);
cr.accept(cv, 0);
return cv.getMethodInfos();
}
public static Method getMethod(Class> clz, String methodName, Class>[] paramTypes) {
while (clz != Object.class) {
Method[] ms = clz.getDeclaredMethods();
for (Method m : ms) {
if (!m.getName().equals(methodName)) {
continue;
}
Class>[] paramTypes2 = m.getParameterTypes();
if (!Arrays.equals(paramTypes2, paramTypes)) {
continue;
}
return m;
}
clz = clz.getSuperclass();
}
return null;
}
public static Class> loadClass(String fullName, byte[] b) throws Exception {
String clzOutPath = AppInfo.get("sumk.asm.debug.output");
if (clzOutPath != null && clzOutPath.length() > 0) {
try {
File f = new File(clzOutPath, fullName + ".class");
try (FileOutputStream fos = new FileOutputStream(f)) {
fos.write(b);
fos.flush();
}
} catch (Exception e) {
if (Logs.asm().isTraceEnabled()) {
Logs.asm().error(e.getLocalizedMessage(), e);
}
}
}
Class> clz = clzMap.get(fullName);
if (clz != null) {
return clz;
}
synchronized (AsmUtils.class) {
clz = clzMap.get(fullName);
if (clz != null) {
return clz;
}
clz = (Class>) defineClass.invoke(Loader.loader(), fullName, b, 0, b.length);
if (clz == null) {
throw new SumkException(-235345436, "cannot load class " + fullName);
}
clzMap.put(fullName, clz);
return clz;
}
}
public static final int BADMODIFIERS = Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.PRIVATE;
public static boolean notPublicOnly(int modifiers) {
return (modifiers & (Modifier.PUBLIC | BADMODIFIERS)) != Modifier.PUBLIC;
}
public static boolean canProxy(int modifiers) {
return (modifiers & BADMODIFIERS) == 0;
}
public static List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy