diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/conf/ConfigInitializer.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/conf/ConfigInitializer.java index 116cb16452357ac79a13342b39f9ddc6ee2503e9..18f5bc61ebd4270078e5cd561b9129dc2f9e9bde 100644 --- a/skywalking-api/src/main/java/com/ai/cloud/skywalking/conf/ConfigInitializer.java +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/conf/ConfigInitializer.java @@ -1,38 +1,40 @@ package com.ai.cloud.skywalking.conf; +import static com.ai.cloud.skywalking.conf.Config.SkyWalking.AUTH_OVERRIDE; +import static com.ai.cloud.skywalking.conf.Config.SkyWalking.AUTH_SYSTEM_ENV_NAME; + import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.LinkedList; import java.util.Properties; -import java.util.logging.Level; -import java.util.logging.Logger; -import static com.ai.cloud.skywalking.conf.Config.SkyWalking.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class ConfigInitializer { - private static Logger logger = Logger.getLogger(ConfigInitializer.class.getName()); + private static Logger logger = LogManager.getLogger(ConfigInitializer.class); public static void initialize() { InputStream inputStream = ConfigInitializer.class.getResourceAsStream("/sky-walking.auth"); if (inputStream == null) { - logger.log(Level.ALL, "No provider sky-walking certification documents, sky-walking api auto shutdown."); + logger.info("No provider sky-walking certification documents, sky-walking api auto shutdown."); } else { try { Properties properties = new Properties(); properties.load(inputStream); initNextLevel(properties, Config.class, new ConfigDesc()); AuthDesc.isAuth = Boolean.valueOf(System.getenv(AUTH_SYSTEM_ENV_NAME)); - logger.log(Level.ALL, "sky-walking auth check : " + AuthDesc.isAuth); + logger.info("sky-walking auth check : " + AuthDesc.isAuth); if(!AuthDesc.isAuth && AUTH_OVERRIDE){ AuthDesc.isAuth = AUTH_OVERRIDE; - logger.log(Level.ALL, "sky-walking auth override: " + AuthDesc.isAuth); + logger.info("sky-walking auth override: " + AuthDesc.isAuth); } } catch (IllegalAccessException e) { - logger.log(Level.ALL, "Parsing certification file failed, sky-walking api auto shutdown."); + logger.error("Parsing certification file failed, sky-walking api auto shutdown.", e); } catch (IOException e) { - logger.log(Level.ALL, "Failed to read the certification file, sky-walking api auto shutdown."); + logger.error("Failed to read the certification file, sky-walking api auto shutdown.", e); } } } diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginBootstrap.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginBootstrap.java new file mode 100644 index 0000000000000000000000000000000000000000..ffcda0f24a5b94ee96900961baa03c72feeed175 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginBootstrap.java @@ -0,0 +1,40 @@ +package com.ai.cloud.skywalking.plugin; + +import java.net.URL; +import java.util.Enumeration; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.ai.cloud.skywalking.conf.AuthDesc; +import com.ai.cloud.skywalking.plugin.interceptor.EnhanceClazz4Interceptor; + +public class PluginBootstrap { + private static Logger logger = LogManager.getLogger(PluginBootstrap.class); + + public void start() { + if (!AuthDesc.isAuth()) { + return; + } + + PluginResourcesResolver resolver = new PluginResourcesResolver(); + Enumeration resources = resolver.getResources(); + + if (resources == null || !resources.hasMoreElements()) { + logger.info("no plugin files (skywalking-plugin.properties) found, continue to start application."); + return; + } + + while (resources.hasMoreElements()) { + URL pluginUrl = resources.nextElement(); + try { + PluginCfg.CFG.load(pluginUrl.openStream()); + } catch (Throwable t) { + logger.error("plugin [{}] init failure.", pluginUrl, t); + } + } + + EnhanceClazz4Interceptor enhanceClazz4Interceptor = new EnhanceClazz4Interceptor(); + enhanceClazz4Interceptor.enhance(); + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginCfg.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginCfg.java new file mode 100644 index 0000000000000000000000000000000000000000..229d6dbfb8af46c5981a5b05a8acd9ec093fa9c2 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginCfg.java @@ -0,0 +1,36 @@ +package com.ai.cloud.skywalking.plugin; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashSet; +import java.util.Set; + +import com.ai.cloud.skywalking.util.StringUtil; + +public class PluginCfg { + public final static PluginCfg CFG = new PluginCfg(); + + private Set interceptorClassList = new HashSet(); + + private PluginCfg(){} + + void load(InputStream input) throws IOException{ + try{ + BufferedReader reader = new BufferedReader(new InputStreamReader(input)); + String nhanceOriginClassName = null; + while((nhanceOriginClassName = reader.readLine()) != null){ + if(!StringUtil.isEmpty(nhanceOriginClassName)){ + interceptorClassList.add(nhanceOriginClassName.trim()); + } + } + }finally{ + input.close(); + } + } + + public Set getInterceptorClassList(){ + return interceptorClassList; + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginResourcesResolver.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginResourcesResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..c311cd689b6ef8c47a71e952e66775b1cf73b923 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginResourcesResolver.java @@ -0,0 +1,49 @@ +package com.ai.cloud.skywalking.plugin; + +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class PluginResourcesResolver { + private static Logger logger = LogManager.getLogger(PluginResourcesResolver.class); + + public Enumeration getResources(){ + Enumeration urls; + try { + urls = getDefaultClassLoader().getResources("skywalking-plugin.properties"); + + if(!urls.hasMoreElements()){ + logger.info("no plugin files (skywalking-plugin.properties) found"); + } + + while(urls.hasMoreElements()){ + URL pluginUrl = urls.nextElement(); + logger.info("find skywalking plugin define in {}", pluginUrl); + } + + return urls; + } catch (IOException e) { + logger.error("read resources failure.", e); + } + return null; + } + + private ClassLoader getDefaultClassLoader() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } + catch (Throwable ex) { + // Cannot access thread context ClassLoader - falling back to system class loader... + } + if (cl == null) { + // No thread context class loader -> use class loader of this class. + cl = PluginResourcesResolver.class.getClassLoader(); + } + return cl; + } + +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/TracingBootstrap.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/TracingBootstrap.java new file mode 100644 index 0000000000000000000000000000000000000000..2d98aa18715a8ff1bc5c99d7b88cb61c84d68250 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/TracingBootstrap.java @@ -0,0 +1,33 @@ +package com.ai.cloud.skywalking.plugin; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * 替代应用函数的main函数入口,确保在程序入口处运行
+ * 用于替代-javaagent的另一种模式
+ * + * @author wusheng + * + */ +public class TracingBootstrap { + private static Logger logger = LogManager.getLogger(TracingBootstrap.class); + + private TracingBootstrap() { + } + + public static void main(String[] args) { + if (args.length == 0) { + throw new RuntimeException( + "bootstrap failure. need args[0] to be main class."); + } + + try { + PluginBootstrap bootstrap = new PluginBootstrap(); + bootstrap.start(); + } catch (Throwable t) { + logger.error("PluginBootstrap start failure.", t); + } + + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..dea537914794d6603f5993dc4b87098f0e90dcb1 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java @@ -0,0 +1,63 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +import java.util.Set; + +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.dynamic.ClassFileLocator; +import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; +import net.bytebuddy.pool.TypePool; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.ai.cloud.skywalking.plugin.PluginCfg; + +public class EnhanceClazz4Interceptor { + private static Logger logger = LogManager + .getLogger(EnhanceClazz4Interceptor.class); + + private TypePool typePool; + + public EnhanceClazz4Interceptor() { + typePool = TypePool.Default.ofClassPath(); + } + + public void enhance() { + Set interceptorClassList = PluginCfg.CFG + .getInterceptorClassList(); + + for (String interceptorClassName : interceptorClassList) { + try { + enhance0(interceptorClassName); + } catch (Throwable t) { + logger.error("enhance class [{}] for intercept failure.", + interceptorClassName, t); + } + } + } + + private void enhance0(String interceptorDefineClassName) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + InterceptorDefine define = (InterceptorDefine)Class.forName(interceptorDefineClassName).newInstance(); + + String enhanceOriginClassName = define.getBeInterceptedClassName(); + /** + * add '$$Origin' at the end of be enhanced classname
+ * such as: class com.ai.cloud.TestClass to class com.ai.cloud.TestClass$$Origin + */ + new ByteBuddy() + .redefine(typePool.describe(enhanceOriginClassName).resolve(), + ClassFileLocator.ForClassLoader.ofClassPath()) + .name(enhanceOriginClassName + "$$Origin") + .make() + .load(ClassLoader.getSystemClassLoader(), + ClassLoadingStrategy.Default.INJECTION).getLoaded(); + + /** + * define class as origin class name. and inject to classloader.
+ * new class need:
+ * 1.implement com.ai.cloud.skywalking.plugin.interceptor.IEnhancedClassInstanceContext();
+ * 2.add field '_$EnhancedClassInstanceContext' of type EnhancedClassInstanceContext + * 3.intercept constructor and method if required by interceptorDefineClass + */ + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhancedClassInstanceContext.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhancedClassInstanceContext.java new file mode 100644 index 0000000000000000000000000000000000000000..f15ceff301293bcbc7a3c9dfbd183f01aeca9a4a --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhancedClassInstanceContext.java @@ -0,0 +1,18 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +import java.util.HashMap; +import java.util.Map; + +/** + * 被增强的类实例,需扩展的context属性,用于在不同的方法,或者构造函数间保存实例 + * + * @author wusheng + * + */ +public class EnhancedClassInstanceContext { + public static final String FIELD_NAME = "_$EnhancedClassInstanceContext"; + + private Map context = new HashMap(); + + +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IAroundInterceptor.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IAroundInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..861fc41072d574d8831b8dcc8af4eba9eded2cef --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IAroundInterceptor.java @@ -0,0 +1,11 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +public interface IAroundInterceptor { + public void onConstruct(EnhancedClassInstanceContext context); + + public void beforeMethod(EnhancedClassInstanceContext context); + + public void afterMethod(EnhancedClassInstanceContext context); + + +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IEnhancedClassInstanceContext.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IEnhancedClassInstanceContext.java new file mode 100644 index 0000000000000000000000000000000000000000..fa7fccd50f45b18a43d6fd646590fa33ff6c336a --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IEnhancedClassInstanceContext.java @@ -0,0 +1,12 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +/** + * 被增强的类,会实现此接口,用于快速获取实例级属性上下文扩展
+ * @see com.ai.cloud.skywalking.plugin.interceptor.EnhanceClazz4Interceptor.enhance0() + * + * @author wusheng + * + */ +public interface IEnhancedClassInstanceContext { + public EnhancedClassInstanceContext getEnhancedClassInstanceContext(); +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorDefine.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorDefine.java new file mode 100644 index 0000000000000000000000000000000000000000..c5101050675d06f45dc255405f6a3930b25f97b8 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorDefine.java @@ -0,0 +1,9 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +public interface InterceptorDefine { + public String getBeInterceptedClassName(); + + public String[] getBeInterceptedMethods(); + + public IAroundInterceptor instance(); +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/selfexamination/SDKHealthCollector.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/selfexamination/SDKHealthCollector.java index d9c6c770f48943f5ac7230d69fb92a4bb3a86538..414e486755a1c46b92771c8745ee1df77c870705 100644 --- a/skywalking-api/src/main/java/com/ai/cloud/skywalking/selfexamination/SDKHealthCollector.java +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/selfexamination/SDKHealthCollector.java @@ -12,7 +12,7 @@ import com.ai.cloud.skywalking.conf.Config; import com.ai.cloud.skywalking.util.BuriedPointMachineUtil; public class SDKHealthCollector extends Thread { - private Logger logger = LogManager.getLogger(SDKHealthCollector.class); + private static Logger logger = LogManager.getLogger(SDKHealthCollector.class); private static Map heathReadings = new ConcurrentHashMap(); diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/ConstructorInterceptor.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/ConstructorInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..2fe37919e6e94c97a49464beef20f5ab84ffcb9e --- /dev/null +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/ConstructorInterceptor.java @@ -0,0 +1,16 @@ +package test.ai.cloud.bytebuddy; + +import net.bytebuddy.implementation.bind.annotation.AllArguments; +import net.bytebuddy.implementation.bind.annotation.RuntimeType; +import net.bytebuddy.implementation.bind.annotation.This; + +public class ConstructorInterceptor { + @RuntimeType + public void intercept(@AllArguments Object[] allArguments) { + System.out + .println("ConstructorInterceptor size:" + allArguments.length); + if(allArguments.length > 0){ + System.out.println("ConstructorInterceptor param[0]=" + allArguments[0]); + } + } +} diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/Interceptor.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/MethodInterceptor.java similarity index 63% rename from skywalking-api/src/test/java/test/ai/cloud/bytebuddy/Interceptor.java rename to skywalking-api/src/test/java/test/ai/cloud/bytebuddy/MethodInterceptor.java index 7180f2b1ca88b4a8f9b69d77fb2879d7dac9eb32..332971af8046c80f3dbda295a6a8f8977ef69082 100644 --- a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/Interceptor.java +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/MethodInterceptor.java @@ -7,12 +7,13 @@ import net.bytebuddy.implementation.bind.annotation.AllArguments; import net.bytebuddy.implementation.bind.annotation.Origin; import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.SuperCall; +import net.bytebuddy.implementation.bind.annotation.This; -public class Interceptor{ +public class MethodInterceptor{ @RuntimeType - public Object intercept(@AllArguments Object[] allArguments, @Origin Method method, @SuperCall Callable zuper){ + public Object intercept(@This Object obj, @AllArguments Object[] allArguments, @Origin Method method, @SuperCall Callable zuper){ try { - return "intercept_" + zuper.call(); + return method.getName() + ":intercept_" + zuper.call(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java index 453c53b6f84d72d822a0151b5d8f4d06758e7a1f..e2e763ca57cab0fa65d100c19a486c094bc7d17d 100644 --- a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java @@ -1,49 +1,56 @@ package test.ai.cloud.bytebuddy; -import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.isConstructor; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; import net.bytebuddy.ByteBuddy; import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.implementation.MethodDelegation; +import net.bytebuddy.implementation.SuperMethodCall; import net.bytebuddy.pool.TypePool; public class SimulateMain { public static void main(String[] args) throws NoSuchFieldException, - SecurityException, InstantiationException, IllegalAccessException { + SecurityException, InstantiationException, IllegalAccessException, ClassNotFoundException { TypePool typePool = TypePool.Default.ofClassPath(); - - Object newClazzObj = new ByteBuddy() - .redefine( - typePool.describe( - "test.ai.cloud.bytebuddy.TestClass") - .resolve(), - ClassFileLocator.ForClassLoader.ofClassPath()) - .name("test.ai.cloud.bytebuddy.TestClass$$Origin") - .make() - .load(ClassLoader.getSystemClassLoader(), - ClassLoadingStrategy.Default.INJECTION).getLoaded().newInstance(); - TestClass t22 = (TestClass)(new ByteBuddy() - .subclass(newClazzObj.getClass()) - .method(named("testA")) - .intercept(MethodDelegation.to(new Interceptor())) + Class newClazz = new ByteBuddy() + .redefine( + typePool.describe("test.ai.cloud.bytebuddy.TestClass") + .resolve(), + ClassFileLocator.ForClassLoader.ofClassPath()) + .name("test.ai.cloud.bytebuddy.TestClass$$Origin") + .make() + .load(ClassLoader.getSystemClassLoader(), + ClassLoadingStrategy.Default.INJECTION).getLoaded(); + + TestClass t22 = (TestClass) (new ByteBuddy() + .subclass(newClazz) + .method(isMethod()) + .intercept(MethodDelegation.to(new MethodInterceptor())) + .constructor(isConstructor()) + .intercept(MethodDelegation.to(new ConstructorInterceptor()).andThen(SuperMethodCall.INSTANCE)) .name("test.ai.cloud.bytebuddy.TestClass") .make() .load(ClassLoader.getSystemClassLoader(), - ClassLoadingStrategy.Default.INJECTION).getLoaded().newInstance()); + ClassLoadingStrategy.Default.INJECTION).getLoaded() + .newInstance()); - //System.out.println(t22.testA("1")); - - TestClass t = new TestClass(); + // System.out.println(t22.testA("1")); + TestClass t = new TestClass("abc"); System.out.println(t.testA("1")); - TestClass t2 = null; - try { - t2 = (TestClass)Class.forName("test.ai.cloud.bytebuddy.TestClass").newInstance(); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - System.out.println(t2.testA("1")); + t = new TestClass("abc"); + System.out.println(t.testA("1")); + +// TestClass t2 = null; +// try { +// t2 = (TestClass) Class.forName("test.ai.cloud.bytebuddy.TestClass") +// .newInstance(); +// } catch (ClassNotFoundException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// System.out.println(t2.testA("1")); } } diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/TestClass.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/TestClass.java index 4a2129badddde53d097576ef0eedbe4bdd6d2c4f..7740bc3b15cf5e4c4409f0964bbd3acd27dcf60f 100644 --- a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/TestClass.java +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/TestClass.java @@ -1,6 +1,15 @@ package test.ai.cloud.bytebuddy; public class TestClass { + public TestClass(){ + //System.out.println("init:" + this.getClass().getName()); + } + + public TestClass(String tmp){ + //System.out.println("init:" + this.getClass().getName()); + } + + public String testA(String aa){ // throw new RuntimeException("adfasdfas"); return "TestClass.testA"; diff --git a/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginResourceResoverTest.java b/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginResourceResoverTest.java new file mode 100644 index 0000000000000000000000000000000000000000..10315a55f1c6b8a7edad7a5f676d90816801d811 --- /dev/null +++ b/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginResourceResoverTest.java @@ -0,0 +1,14 @@ +package test.ai.cloud.plugin; + +import java.io.IOException; + +import com.ai.cloud.skywalking.plugin.PluginResourcesResolver; + +public class PluginResourceResoverTest { + + public static void main(String[] args) throws IOException { + PluginResourcesResolver resolver = new PluginResourcesResolver(); + resolver.getResources(); + } + +} diff --git a/skywalking-api/src/test/resources/log4j2.xml b/skywalking-api/src/test/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..4559d6d69d14f3e063d42022492a971bcd0dd5a3 --- /dev/null +++ b/skywalking-api/src/test/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/skywalking-api/src/test/resources/skywalking-plugin.properties b/skywalking-api/src/test/resources/skywalking-plugin.properties new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391