Fix Dependency

This commit is contained in:
坏黑 2019-07-13 15:57:36 +08:00
parent 90c76d72cc
commit 651291b187
8 changed files with 121 additions and 43 deletions

View File

@ -26,10 +26,10 @@ import java.util.concurrent.Executors;
* 注意与 TabooLib4.x 版本的兼容 * 注意与 TabooLib4.x 版本的兼容
* 可能存在同时运行的情况 * 可能存在同时运行的情况
*/ */
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.slf4j:slf4j-api:1.7.25", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/org.slf4j-slf4j-api-1.7.25.jar") @Dependency(maven = "org.slf4j:slf4j-api:1.7.25", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/org.slf4j-slf4j-api-1.7.25.jar")
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.1.0", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/com.zaxxer-HikariCP-3.1.0.jar") @Dependency(maven = "com.zaxxer:HikariCP:3.1.0", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/com.zaxxer-HikariCP-3.1.0.jar")
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.scala-lang:scala-library:2.12.8", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/scala-library-2.12.8.jar") @Dependency(maven = "org.scala-lang:scala-library:2.12.8", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/scala-library-2.12.8.jar")
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.google.inject:guice:4.2.2", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/guice-4.2.2.jar") @Dependency(maven = "com.google.inject:guice:4.2.2", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/guice-4.2.2.jar")
public class TabooLib { public class TabooLib {
private static TabooLib inst = new TabooLib(); private static TabooLib inst = new TabooLib();

View File

@ -29,7 +29,7 @@ public class TabooLibLoader {
static void init() { static void init() {
// 加载依赖 // 加载依赖
TDependencyInjector.inject("TabooLib", TabooLib.class); TDependencyInjector.inject(TabooLib.getPlugin(), TabooLib.class);
// 插件统计 // 插件统计
Metrics metrics = new Metrics(TabooLib.getPlugin()); Metrics metrics = new Metrics(TabooLib.getPlugin());
metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(TabooLibAPI::isDependTabooLib).count()))); metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(TabooLibAPI::isDependTabooLib).count())));

View File

@ -7,12 +7,6 @@ import java.lang.annotation.*;
@Repeatable(Dependencies.class) @Repeatable(Dependencies.class)
public @interface Dependency { public @interface Dependency {
enum Type {PLUGIN, LIBRARY}
Type type();
String plugin() default "";
String maven() default ""; String maven() default "";
String mavenRepo() default TDependency.MAVEN_REPO; String mavenRepo() default TDependency.MAVEN_REPO;

View File

@ -0,0 +1,71 @@
package io.izzel.taboolib.module.dependency;
import io.izzel.taboolib.TabooLib;
import io.izzel.taboolib.TabooLibAPI;
import io.izzel.taboolib.util.Strings;
import org.bukkit.plugin.Plugin;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;
/**
* @Author 坏黑
* @Since 2019-07-13 15:25
*/
public class DependencyAnnotationVisitor extends AnnotationVisitor {
private Plugin plugin;
private String maven;
private String mavenRepo = TDependency.MAVEN_REPO;
private String url = "";
public DependencyAnnotationVisitor(Plugin plugin, AnnotationVisitor annotationVisitor) {
super(Opcodes.ASM5, annotationVisitor);
this.plugin = plugin;
}
@Override
public void visit(String name, Object value) {
switch (name) {
case "maven":
maven = String.valueOf(value);
break;
case "mavenRepo":
mavenRepo = String.valueOf(value);
break;
case "url":
url = String.valueOf(value);
break;
}
super.visit(name, value);
}
@Override
public void visitEnum(String name, String descriptor, String value) {
super.visitEnum(name, descriptor, value);
}
@Override
public AnnotationVisitor visitAnnotation(String name, String descriptor) {
return new DependencyAnnotationVisitor(plugin, super.visitAnnotation(name, descriptor));
}
@Override
public AnnotationVisitor visitArray(String name) {
return new DependencyAnnotationVisitor(plugin, super.visitArray(name));
}
@Override
public void visitEnd() {
if (maven != null) {
if (TDependency.requestLib(maven, mavenRepo, url)) {
TabooLibAPI.debug(" Loaded " + String.join(":", maven) + " (" + plugin.getName() + ")");
} else {
TabooLib.getLogger().warn(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("DEPENDENCY-LOAD-FAIL"), plugin.getName(), String.join(":", maven)));
}
maven = null;
mavenRepo = TDependency.MAVEN_REPO;
url = "";
}
super.visitEnd();
}
}

View File

@ -0,0 +1,25 @@
package io.izzel.taboolib.module.dependency;
import org.bukkit.plugin.Plugin;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
/**
* @Author sky
* @Since 2019-7-13 15:17
*/
public class DependencyClassVisitor extends ClassVisitor {
private Plugin plugin;
public DependencyClassVisitor(Plugin plugin, ClassVisitor classVisitor) {
super(Opcodes.ASM5, classVisitor);
this.plugin = plugin;
}
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return new DependencyAnnotationVisitor(plugin, super.visitAnnotation(descriptor, visible));
}
}

View File

@ -1,40 +1,31 @@
package io.izzel.taboolib.module.dependency; package io.izzel.taboolib.module.dependency;
import io.izzel.taboolib.TabooLib; import io.izzel.taboolib.util.Files;
import io.izzel.taboolib.TabooLibAPI;
import io.izzel.taboolib.util.Strings;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
/** /**
* @author Izzel_Aliz * @author Izzel_Aliz
*/ */
public class TDependencyInjector { public class TDependencyInjector {
public static Dependency[] getDependencies(Class<?> clazz) { private static boolean libInjected;
Dependency[] dependencies = new Dependency[0];
Dependencies d = clazz.getAnnotation(Dependencies.class);
if (d != null) {
dependencies = d.value();
}
Dependency d2 = clazz.getAnnotation(Dependency.class);
if (d2 != null) {
dependencies = new Dependency[] {d2};
}
return dependencies;
}
public static void inject(Plugin plugin, Class<?> clazz) { public static void inject(Plugin plugin, Class<?> clazz) {
inject(plugin.getName(), clazz); if (!plugin.getName().equals("TabooLib") || !libInjected) {
} try {
ClassReader classReader = new ClassReader(Files.getResource(plugin, clazz.getName().replace(".", "/") + ".class"));
public static void inject(String name, Class<?> clazz) { ClassWriter classWriter = new ClassWriter(0);
for (Dependency dependency : getDependencies(clazz)) { ClassVisitor classVisitor = new DependencyClassVisitor(plugin, classWriter);
if (dependency.type() == Dependency.Type.LIBRARY) { classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES);
if (TDependency.requestLib(dependency.maven(), dependency.mavenRepo(), dependency.url())) { classWriter.visitEnd();
TabooLibAPI.debug(" Loaded " + String.join(":", dependency.maven()) + " (" + name + ")"); classVisitor.visitEnd();
} else { } catch (Throwable t) {
TabooLib.getLogger().warn(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("DEPENDENCY-LOAD-FAIL"), name, String.join(":", dependency.maven()))); t.printStackTrace();
} } finally {
libInjected = true;
} }
} }
} }

View File

@ -1,5 +1,6 @@
package io.izzel.taboolib.module.dependency; package io.izzel.taboolib.module.dependency;
import io.izzel.taboolib.common.plugin.InternalPlugin;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -16,7 +17,7 @@ public class TDependencyLoader {
try { try {
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true); method.setAccessible(true);
method.invoke(Bukkit.class.getClassLoader(), url); method.invoke(plugin instanceof InternalPlugin ? Bukkit.class.getClassLoader() : plugin.getClass().getClassLoader(), url);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -29,5 +30,4 @@ public class TDependencyLoader {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@ -1,9 +1,6 @@
package io.izzel.taboolib.module.lite; package io.izzel.taboolib.module.lite;
import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.*;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.stream.IntStream; import java.util.stream.IntStream;