Runtime code generation for the Java virtual machine.

Overview

Byte Buddy

Byte Buddy logo

runtime code generation for the Java virtual machine

Actions Status Security Score Coverage Status Maven Central

Byte Buddy is a code generation and manipulation library for creating and modifying Java classes during the runtime of a Java application and without the help of a compiler. Other than the code generation utilities that ship with the Java Class Library, Byte Buddy allows the creation of arbitrary classes and is not limited to implementing interfaces for the creation of runtime proxies. Furthermore, Byte Buddy offers a convenient API for changing classes either manually, using a Java agent or during a build.

In order to use Byte Buddy, one does not require an understanding of Java byte code or the class file format. In contrast, Byte Buddy’s API aims for code that is concise and easy to understand for everybody. Nevertheless, Byte Buddy remains fully customizable down to the possibility of defining custom byte code. Furthermore, the API was designed to be as non-intrusive as possible and as a result, Byte Buddy does not leave any trace in the classes that were created by it. For this reason, the generated classes can exist without requiring Byte Buddy on the class path. Because of this feature, Byte Buddy’s mascot was chosen to be a ghost.

Byte Buddy is written in Java 5 but supports the generation of classes for any Java version. Byte Buddy is a light-weight library and only depends on the visitor API of the Java byte code parser library ASM which does itself not require any further dependencies.

At first sight, runtime code generation can appear to be some sort of black magic that should be avoided and only few developers write applications that explicitly generate code during their runtime. However, this picture changes when creating libraries that need to interact with arbitrary code and types that are unknown at compile time. In this context, a library implementer must often choose between either requiring a user to implement library-proprietary interfaces or to generate code at runtime when the user’s types becomes first known to the library. Many known libraries such as for example Spring or Hibernate choose the latter approach which is popular among their users under the term of using Plain Old Java Objects. As a result, code generation has become an ubiquitous concept in the Java space. Byte Buddy is an attempt to innovate the runtime creation of Java types in order to provide a better tool set to those relying on code generation.


Duke's Choice award

In October 2015, Byte Buddy was distinguished with a Duke's Choice award by Oracle. The award appreciates Byte Buddy for its "tremendous amount of innovation in Java Technology". We feel very honored for having received this award and want to thank all users and everybody else who helped making Byte Buddy the success it has become. We really appreciate it!


Byte Buddy offers excellent performance at production quality. It is stable and in use by distinguished frameworks and tools such as Mockito, Hibernate, Jackson, Google's Bazel build system and many others. Byte Buddy is also used by a large number of commercial products to great result. It is currently downloaded over 75 million times a year.

Hello World

Saying Hello World with Byte Buddy is as easy as it can get. Any creation of a Java class starts with an instance of the ByteBuddy class which represents a configuration for creating new types:

Class<?> dynamicType = new ByteBuddy()
  .subclass(Object.class)
  .method(ElementMatchers.named("toString"))
  .intercept(FixedValue.value("Hello World!"))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded();
assertThat(dynamicType.newInstance().toString(), is("Hello World!"));

The default ByteBuddy configuration which is used in the above example creates a Java class in the newest version of the class file format that is understood by the processing Java virtual machine. As hopefully obvious from the example code, the created type will extend the Object class and overrides its toString method which should return a fixed value of Hello World!. The method to be overridden is identified by a so-called ElementMatcher. In the above example, a predefined element matcher named(String) is used which identifies methods by their exact names. Byte Buddy comes with numerous predefined and well-tested matchers which are collected in the ElementMatchers class and which can be easily composed. The creation of custom matchers is however as simple as implementing the (functional) ElementMatcher interface.

For implementing the toString method, the FixedValue class defines a constant return value for the overridden method. Defining a constant value is only one example of many method interceptors that ship with Byte Buddy. By implementing the Implementation interface, a method could however even be defined by custom byte code.

Finally, the described Java class is created and then loaded into the Java virtual machine. For this purpose, a target class loader is required. Eventually, we can convince ourselves of the result by calling the toString method on an instance of the created class and finding the return value to represent the constant value we expected.

A more complex example

Of course, a Hello World example is a too simple use case for evaluating the quality of a code generation library. In reality, a user of such a library wants to perform more complex manipulations, for example by introducing hooks into the execution path of a Java program. Using Byte Buddy, doing so is however equally simple. The following example gives a taste of how method calls can be intercepted.

Byte Buddy expresses dynamically defined method implementations by instances of the Implementation interface. In the previous example, FixedValue that implements this interface was already demonstrated. By implementing this interface, a user of Byte Buddy can go to the length of defining custom byte code for a method. Normally, it is however easier to use Byte Buddy's predefined implementations such as MethodDelegation which allows for implementing any method in plain Java. Using this implementation is straight forward as it operates by delegating the control flow to any POJO. As an example of such a POJO, Byte Buddy can for example redirect a call to the only method of the following class:

public class GreetingInterceptor {
  public Object greet(Object argument) {
    return "Hello from " + argument;
  }
}

Note that the above GreetingInterceptor does not depend on any Byte Buddy type. This is good news because none of the classes that Byte Buddy generates require Byte Buddy on the class path! Given the above GreetingInterceptor, we can use Byte Buddy to implement the Java 8 java.util.function.Function interface and its abstract apply method:

Class<? extends java.util.function.Function> dynamicType = new ByteBuddy()
  .subclass(java.util.function.Function.class)
  .method(ElementMatchers.named("apply"))
  .intercept(MethodDelegation.to(new GreetingInterceptor()))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded();
assertThat((String) dynamicType.newInstance().apply("Byte Buddy"), is("Hello from Byte Buddy"));

Executing the above code, Byte Buddy implements Java's Function interface and implements the apply method as a delegation to an instance of the GreetingInterceptor POJO that we defined before. Now, every time that the Function::apply method is called, the control flow is dispatched to GreetingInterceptor::greet and the latter method's return value is returned from the interface's method.

Interceptors can be defined to take with more generic inputs and outputs by annotating the interceptor's parameters. When Byte Buddy discovers an annotation, the library injects the dependency that the interceptor parameter requires. An example for a more general interceptor is the following class:

public class GeneralInterceptor {
  @RuntimeType
  public Object intercept(@AllArguments Object[] allArguments,
                          @Origin Method method) {
    // intercept any method of any signature
  }
}

With the above interceptor, any intercepted method could be matched and processed. For example, when matching Function::apply, the method's arguments would be passed as the single element of an array. Also, a Method reference to Fuction::apply would be passed as the interceptor's second argument due to the @Origin annotation. By declaring the @RuntimeType annotation on the method, Byte Buddy finally casts the returned value to the return value of the intercepted method if this is necessary. In doing so, Byte Buddy also applies automatic boxing and unboxing.

Besides the annotations that were already mentioned there exist plenty of other predefined annotations. For example, when using the @SuperCall annotation on a Runnable or Callable type, Byte Buddy injects proxy instances that allow for an invocation of a non-abstract super method if such a method exists. And even if Byte Buddy does not cover a use case, Byte Buddy offers an extension mechanism for defining custom annotations.

You might expect that using these annotations ties your code to Byte Buddy. However, Java ignores annotations in case that they are not visible to a class loader. This way, generated code can still exist without Byte Buddy! You can find more information on the MethodDelegation and on all of its predefined annotations in its javadoc and in Byte Buddy's tutorial.

Changing existing classes

Byte Buddy is not limited to creating subclasses but is also capable of redefining existing code. To do so, Byte Buddy offers a convenient API for defining so-called Java agents. Java agents are plain old Java programs that can be used to alter the code of an existing Java application during its runtime. As an example, we can use Byte Buddy to change methods to print their execution time. For this, we first define an interceptor similar to the interceptors in the previous examples:

public class TimingInterceptor {
  @RuntimeType
  public static Object intercept(@Origin Method method, 
                                 @SuperCall Callable<?> callable) {
    long start = System.currentTimeMillis();
    try {
      return callable.call();
    } finally {
      System.out.println(method + " took " + (System.currentTimeMillis() - start));
    }
  }
}

Using a Java agent, we can now apply this interceptor to all types that match an ElementMatcher for a TypeDescription. For the example, we choose to add the above interceptor to all types with a name that ends in Timed. This is done for the sake of simplicity whereas an annotation would probably be a more appropriate alternative to mark such classes for a production agent. Using Byte Buddy's AgentBuilder API, creating a Java agent is as easy as defining the following agent class:

public class TimerAgent {
  public static void premain(String arguments, 
                             Instrumentation instrumentation) {
    new AgentBuilder.Default()
      .type(ElementMatchers.nameEndsWith("Timed"))
      .transform((builder, type, classLoader, module) -> 
          builder.method(ElementMatchers.any())
                 .intercept(MethodDelegation.to(TimingInterceptor.class))
      ).installOn(instrumentation);
  }
}

Similar to Java's main method, the premain method is the entry point to any Java agent from which we apply the redefinition. As one argument, a Java agent receives an instance of the Instrumentation interface which allows Byte Buddy to hook into the JVM's standard API for runtime class redefinition.

This program is packaged together with a manifest file with the Premain-Class attribute pointing to the TimerAgent. The resulting jar file can now be added to any Java application by setting -javaagent:timingagent.jar similar to adding a jar to the class path. With the agent active, all classes ending in Timed do now print their execution time to the console.

Byte Buddy is also capable of applying so-called runtime attachments by disabling class file format changes and using the Advice instrumentation. Please refer to the javadoc of the Advice and the AgentBuilder class for further information. Byte Buddy also offers the explicit change of Java classes via a ByteBuddy instance or by using the Byte Buddy Maven and Gradle plugins.

Where to go from here?

Byte Buddy is a comprehensive library and we only scratched the surface of Byte Buddy's capabilities. However, Byte Buddy aims for being easy to use by providing a domain-specific language for creating classes. Most runtime code generation can be done by writing readable code and without any knowledge of Java's class file format. If you want to learn more about Byte Buddy, you can find such a tutorial on Byte Buddy's web page (There is also a Chinese translation available).

Furthermore, Byte Buddy comes with a detailed in-code documentation and extensive test case coverage which can also serve as example code. Finally, you can find an up-to-date list of articles and presentations on Byte Buddy in the wiki. When using Byte Buddy, make also sure to read the following information on maintaining a project dependency.

Getting support

Commercial

The use of Byte Buddy is free and does not require the purchase of a license. To get the most out of the library or to secure an easy start, it is however possible to purchase training, development hours or support plans. Rates are dependent on the scope and duration of an engagement. Please get in touch with [email protected] for further information.

Tidelift

Byte Buddy is listed on Tidelift. If you are not using Byte Buddy to an extent where you want to purchase explicit support and want to support the open source community in general, please consider a subscription.

Free

General questions can be asked on Stack Overflow or on the Byte Buddy mailing list which also serve as an archive for questions. Of course, bug reports will be considered also outside of a commercial plan. For open source projects, it is sometimes possible to receive extended help for taking Byte Buddy into use.

Dependency and API evolution

Byte Buddy is written on top of ASM, a mature and well-tested library for reading and writing compiled Java classes. In order to allow for advanced type manipulations, Byte Buddy is intentionally exposing the ASM API to its users. Of course, the direct use of ASM remains fully optional and most users will most likely never require it. This choice was made such that a user of Byte Buddy is not restrained to its higher-level functionality but can implement custom implementations without a fuss when it is necessary.

ASM has previously changed its public API but added a mechanism for API compatibility starting with version 4 of the library. In order to avoid version conflicts with such older versions, Byte Buddy repackages the ASM dependency into its own namespace. If you want to use ASM directly, the byte-buddy-dep artifact offers a version of Byte Buddy with an explicit dependency to ASM. When doing so, you must repackage both Byte Buddy and ASM into your namespace to avoid version conflicts.

License and development

Byte Buddy is licensed under the liberal and business-friendly Apache Licence, Version 2.0 and is freely available on GitHub. Additionally, the byte-buddy distribution bundles ASM which is released under a 3-clause BSD license.

Byte Buddy binaries are published to the repositories of Maven Central and on JCenter. The artifacts signatures can be validated against this PGP public key beginning with Byte Buddy 1.10.3. Older versions can be validated against this older and weaker certificate.

The project is built using Maven. From your shell, cloning and building the project would go something like this:

git clone https://github.com/raphw/byte-buddy.git
cd byte-buddy
mvn package

On these commands, Byte Buddy is cloned from GitHub and built on your machine. Further build options are listed in the root POM file. Byte Buddy is currently tested for versions 6 and upwards of the JDK on CI servers.

Please use GitHub's issue tracker for reporting bugs. When committing code, please provide test cases that prove the functionality of your features or that demonstrate a bug fix. Furthermore, make sure you are not breaking any existing test cases. If possible, please take the time to write some documentation. For feature requests or general feedback, you can also use the issue tracker or contact us on our mailing list.

Supporters

The work on Byte Buddy is also possible thanks to a row of supporters that have dedicated regular resources and attention to the project. Please take your time to have a look at those supporters and their offerings.

Scienta AS       Instana       Sqreen       Elastic
Comments
  • Implementing a profiler agen with Byte Buddy which automatically attaches

    Implementing a profiler agen with Byte Buddy which automatically attaches

    Hi,

    I'm the developer of stagemonitor and I'm considering replacing the Javassist-based profiler with Byte Buddy. It would be great if you could help me out as I'm stuck.

    I've created an example project for a Byte Buddy proof of concept which touches the most important areas: https://github.com/felixbarny/byte-buddy-test/blob/master/src/test/java/net/bytebuddy/test/TestByteBuddyProfiler.java

    • Runtime attachment
    • Capture signature in custom format
    • Capture method arguments
    • Insert profiling code on enter and on exit

    I also am not sure whether the AgentBuilder or the @Advice API is preferable and if those two approaches can be combined.

    Thx in advance.

    enhancement question 
    opened by felixbarny 139
  • IBM J9 error

    IBM J9 error

    Hi

    SkyWalking gets reports from users in J9 VM. I am not familiar with that. Based on the logs, https://github.com/apache/skywalking/issues/2652#issuecomment-492062199. SkyWalking ProtectiveShieldMatcher prints the logs, such as this

    WARN 2019-05-14 10:58:35:839 main ProtectiveShieldMatcher :  Byte-buddy occurs exception when match type. 
    java.lang.IllegalStateException: Cannot resolve type description for java.util.Properties
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.pool.TypePool$Resolution$Illegal.resolve(TypePool.java:159)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.pool.TypePool$Default$WithLazyResolution$LazyTypeDescription.delegate(TypePool.java:1407)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.description.type.TypeDescription$AbstractBase$OfSimpleType$WithDelegation.getSuperClass(TypeDescription.java:8024)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.description.type.TypeDescription$Generic$OfNonGenericType.getSuperClass(TypeDescription.java:3619)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.description.type.TypeDefinition$SuperClassIterator.next(TypeDefinition.java:314)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.description.type.TypeDefinition$SuperClassIterator.next(TypeDefinition.java:281)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.HasSuperTypeMatcher.matches(HasSuperTypeMatcher.java:53)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.HasSuperTypeMatcher.matches(HasSuperTypeMatcher.java:31)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.ElementMatcher$Junction$Conjunction.matches(ElementMatcher.java:122)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.ElementMatcher$Junction$Disjunction.matches(ElementMatcher.java:160)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.ElementMatcher$Junction$Disjunction.matches(ElementMatcher.java:160)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.ElementMatcher$Junction$Disjunction.matches(ElementMatcher.java:160)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.ElementMatcher$Junction$Disjunction.matches(ElementMatcher.java:160)
    

    I tried to add some ignore rules for these classes, https://github.com/apache/skywalking/compare/j9-compatible , but look like doesn't work.

    ProtectiveShieldMatcher is following our former discussion, it should just simply print the logs and return false as a fail-safe.

    /**
     * In some cases, some frameworks and libraries use some binary codes tech too. From the community feedback, some of
     * them have compatible issues with byte-buddy core, which trigger "Can't resolve type description" exception.
     *
     * So I build this protective shield by a nested matcher. When the origin matcher(s) can't resolve the type, the
     * SkyWalking agent ignores this types.
     *
     * Notice: this ignore mechanism may miss some instrumentations, but at most cases, it's same. If missing happens,
     * please pay attention to the WARNING logs.
     *
     * @author wu-sheng
     */
    public class ProtectiveShieldMatcher<T> extends ElementMatcher.Junction.AbstractBase<T> {
        private static final ILog logger = LogManager.getLogger(ProtectiveShieldMatcher.class);
    
        private final ElementMatcher<? super T> matcher;
    
        public ProtectiveShieldMatcher(ElementMatcher<? super T> matcher) {
            this.matcher = matcher;
        }
    
        public boolean matches(T target) {
            try {
                return this.matcher.matches(target);
            } catch (Throwable t) {
                logger.warn(t, "Byte-buddy occurs exception when match type.");
                return false;
            }
        }
    }
    

    But this time, it is JVM related classes or eclipse osgi related. does J9VM have some protection mechanism? How should I change the codes?

    question 
    opened by wu-sheng 45
  • [Question] An unexpected issue for JDK 9

    [Question] An unexpected issue for JDK 9

    Hi

    We are adding the plugin by using the bootstrap plugin of HttpClient in https://github.com/apache/skywalking/pull/3171.

    java.lang.IllegalAccessError: superinterface check failed: class sun.net.www.http.HttpClient (in module java.base) cannot access class org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance (in unnamed module @0x555590) because module java.base does not read unnamed module @0x555590
    

    What we did is, EnhancedInstance interface added to the target class, implement it dynamically like this https://github.com/apache/skywalking/blob/c76fb4053e/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java#L123-L125

    EnhancedInstance has been injected to bootstrap classloader, but look like there is a model definition to take care in JDK9. What should I do to make this compatible in both JDK9+ and old JDK?

    question 
    opened by wu-sheng 39
  • [Question] How to intercept java.lang.Thread

    [Question] How to intercept java.lang.Thread

    Here is my code, but not working.

    public static void main(String[] args) throws Exception {
            premain(null, ByteBuddyAgent.install());
            doMain();
        }
    
        private static void doMain() throws Exception {
            Thread thread = new Thread();
            thread.getName();
        }
    
        public static void premain(String arg, Instrumentation instrumentation) throws Exception {
            String interceptor = "bytebuddy.GeneralInterceptor";
            ClassFileLocator locator = ClassFileLocator.ForClassLoader.ofSystemLoader();
            TypePool pool = TypePool.Default.of(locator);
            final TypeDescription target = pool.describe(interceptor).resolve();
    
            File temp = Files.createTempDirectory("tmp").toFile();
            ClassInjector.UsingInstrumentation
                    .of(temp, ClassInjector.UsingInstrumentation.Target.BOOTSTRAP, instrumentation)
                    .injectRaw(Collections.singletonMap(interceptor, locator.locate(interceptor).resolve()));
    
            new AgentBuilder.Default()
                    .ignore(ElementMatchers.nameStartsWith("net.bytebuddy."))
                    .with(new AgentBuilder.InjectionStrategy.UsingUnsafe.OfFactory(ClassInjector.UsingUnsafe.Factory.resolve(instrumentation)))
                    .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                    .type(ElementMatchers.named("java.lang.Thread"))
                    .transform(new AgentBuilder.Transformer() {
                        @Override
                        public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule) {
                            return builder.method(ElementMatchers.named("getName")).intercept(MethodDelegation.to(target));
                        }
                    }).installOn(instrumentation);
        }
    
    public class GeneralInterceptor {
    
        @RuntimeType
        public static Object intercept(@This Object thisObj, @AllArguments Object[] allArguments,
                                @Origin Method method, @SuperCall Callable<?> callable) throws Exception {
            // intercept any method of any signature
            System.out.println("===============================GeneralInterceptor");
            return callable.call();
        }
    }
    
    question 
    opened by dengliming 38
  • byte buddy issue

    byte buddy issue

    Hi @raphw :

    I sort of get two issues, one is when i use mockk library and the other when i use mockito and with kotlin classes plus java mixed so i have powermockito also involved

    1. Case1 : When using mockito:
    java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
    
    at org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:74)
    at com.sun.proxy.$Proxy12.isTypeMockable(Unknown Source)
    at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:29)
    at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
    at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:238)
    at org.mockito.internal.creation.MockSettingsImpl.build(MockSettingsImpl.java:226)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:68)
    at org.mockito.Mockito.mock(Mockito.java:1895)
    at com.app.movie.home.model.MoviesModelAdapterImplTest.setUp(MoviesModelAdapterImplTest.kt:90)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
    Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@7d417077
    at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:54)
    at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:57)
    at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:44)
    at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:21)
    at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:18)
    at org.mockito.internal.configuration.GlobalConfiguration.tryGetPluginAnnotationEngine(GlobalConfiguration.java:55)
    at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:68)
    at org.mockito.internal.runners.DefaultInternalRunner$1.withBefores(DefaultInternalRunner.java:39)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:276)
    ... 30 more
    Caused by: org.mockito.exceptions.base.MockitoInitializationException: 
    Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)
    
    Java               : 1.8
    JVM vendor name    : JetBrains s.r.o
    JVM vendor version : 25.152-b01
    JVM name           : OpenJDK 64-Bit Server VM
    JVM version        : 1.8.0_152-release-1024-b01
    JVM info           : mixed mode
    OS name            : Mac OS X
    OS version         : 10.12.6
    
    at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.<init>(InlineByteBuddyMockMaker.java:171)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:49)
    ... 38 more
    Caused by: java.lang.IllegalStateException: Error during attachment using: net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@5ba23b66
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:384)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:358)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:326)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:312)
    at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.<clinit>(InlineByteBuddyMockMaker.java:101)
    ... 44 more
    Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at net.bytebuddy.agent.Attacher.install(Attacher.java:84)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:379)
    ... 48 more
    Caused by: java.lang.NullPointerException
    at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:182)
    ... 54 more
    
    
    Process finished with exit code 255
    

    case 2 : When i use mockk library:

    "/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java" -ea -Didea.test.cyclic.buffer.size=1048576 -Didea.launcher.port=51088 "-Didea.launcher.bin.path=/Applications/Android Studio.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/Android Studio.app/Contents/lib/idea_rt.jar:/Applications/Android Studio.app/Contents/plugins/junit/lib/junit-rt.jar:/Applications/Android Studio.app/Contents/plugins/junit/lib/junit5-rt.jar:/Users/xyz/Library/Android/sdk/platforms/android-27/data/res:/Users/xyz/Documents/androidapp/app/build/intermediates/classes/test/debug:/Users/xyz/Documents/androidapp/app/build/intermediates/classes/debug:/Users/xyz/Documents/androidapp/app/build/tmp/kotlin-classes/debug:/Users/xyz/Documents/androidapp/app/build/tmp/kapt3/classes/debug:/Users/xyz/Documents/androidapp/app/build/generated/res/rs/debug:/Users/xyz/Documents/androidapp/app/build/generated/res/resValues/debug:/Users/xyz/Documents/androidapp/app/build/tmp/kotlin-classes/debugUnitTest:/Users/xyz/Documents/androidapp/app/build/tmp/kapt3/classes/debugUnitTest:/Users/xyz/Documents/androidapp/app/build/intermediates/sourceFolderJavaResources/test/debug:/Users/xyz/Library/Android/sdk/extras/m2repository/com/android/support/constraint/constraint-layout-solver/1.0.2/constraint-layout-solver-1.0.2.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/transition-27.0.2.aar/d0e64e448c75e9ee4777aaa027c17ff8/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/transition-27.0.2.aar/d0e64e448c75e9ee4777aaa027c17ff8/res:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-classloading-xstream/2.0.0-beta.5/7967431c9254796e7a4b26163af98f2e93f1e165/powermock-classloading-xstream-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/espresso-idling-resource-2.2.2.aar/30fca4e6285b2d84ddeb18ab6e9c7e06/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.objenesis/objenesis/2.6/639033469776fd37c08358c6b92a4761feb2af4b/objenesis-2.6.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.2.61/5bc44acc4b3f0d19166ae3e50454b41e8ff29335/kotlin-stdlib-1.2.61.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/animated-vector-drawable-27.0.2.aar/341ac82ee9a02be15e8f8a097c2ea6b2/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-compat-27.0.2.aar/20fbb3976a74fea0cb088259143d6f21/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-compat-27.0.2.aar/20fbb3976a74fea0cb088259143d6f21/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy/1.8.0/f7c50fcf1fab4fa3e148ecf6b329f01f733ed427/byte-buddy-1.8.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/io.mockk/mockk-common/1.8.7/b4321b8ebedab43f98f63816406640f714db6cc/mockk-common-1.8.7.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.7/751f548c85fa49f330cecbb1875893f971b33c4e/gson-2.7.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/io.mockk/mockk-dsl-jvm/1.8.7/4a9859e8921cddec4ab98d49141099632e944550/mockk-dsl-jvm-1.8.7.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.google.dagger/dagger/2.11/95037eaee68aa48021511972e9db9ba29916e1c9/dagger-2.11.jar:/Users/xyz/Documents/androidapp/app/build/intermediates/unmocked-androidapp.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.hamcrest/java-hamcrest/2.0.0.0/f1c8853ade0ecf707f5a261c830e98893983813/java-hamcrest-2.0.0.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-module-junit4-rule-agent/2.0.0-beta.5/65f0811f9f35212a9e40a800f66fced4e7d12f15/powermock-module-junit4-rule-agent-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-vector-drawable-27.0.2.aar/a0946da64cbb196be8e2a164dca5bf2c/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-core-utils-27.0.2.aar/e042b239a51e15ddcd73e182625f487b/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/xpp3/xpp3_min/1.1.4c/19d4e90b43059058f6e056f794f0ea4030d60b86/xpp3_min-1.1.4c.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-module-junit4-common/2.0.0-beta.5/cb845360267ab2dfac0ac1d59819501a66ccd139/powermock-module-junit4-common-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.2.61/6fd5bcfc9ffc446dd147ea006bee7ef5f0ad8ca4/kotlin-reflect-1.2.61.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy/1.8.8/2c570a7c72ef377bf6d99e997bc04c761ecf60a9/byte-buddy-1.8.8.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/FlowTextView-2.0.5.aar/1d43acb03039a028984a9e26148569b6/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/retrofit/2.3.0/bcacde6a8ccedcc56c127403d26b76072fe6214d/retrofit-2.3.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.2.61/bc77c34ff80df88b4d9b0418ea4ae758544573f3/kotlin-stdlib-jdk7-1.2.61.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/converter-gson/2.0.1/2780d858273ce1bb90f6b12e1ef0d40f7741fca/converter-gson-2.0.1.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/javax.annotation/jsr250-api/1.0/5025422767732a1ab45d93abfea846513d742dcf/jsr250-api-1.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/io.reactivex.rxjava2/rxjava/2.1.0/2fdf84dedcaaeabb9d70cde9dbb8aad4eccb80a1/rxjava-2.1.0.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/fontawesome-typeface-4.7.0.2.aar/80a1de4570dbd0041ae2753fd9b7c10f/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/fontawesome-typeface-4.7.0.2.aar/80a1de4570dbd0041ae2753fd9b7c10f/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/3.8.0/5a11f020cce2d11eb71ba916700600e18c4547e7/okhttp-3.8.0.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/gifdecoder-4.6.1.aar/113cc4c67888ca422b1fc3a2e9deaa58/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/disklrucache/4.6.1/2f82d433b9dae134a9b32039a6b5b38abe8a1c46/disklrucache-4.6.1.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-api-support/2.0.0-beta.5/613616628925ecc461ed8b826e44b0c4928261e0/powermock-api-support-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-classloading-base/2.0.0-beta.5/cb04ff970ea19a8466ea6267b45d83b137d5326a/powermock-classloading-base-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-module-junit4/2.0.0-beta.5/4863d6a71361f1aaa7c162146646c50a47e97ee3/powermock-module-junit4-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.javassist/javassist/3.22.0-CR2/44eaf0990dea92f4bca4b9931b2239c0e8756ee7/javassist-3.22.0-CR2.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-v4-27.0.2.aar/de67e6fb5fb33ae7d3193be03692d7ab/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/io.mockk/mockk-agent-common/1.8.7/89d6f678ee414963b87c586aca710b329c75d889/mockk-agent-common-1.8.7.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.thoughtworks.xstream/xstream/1.4.10/dfecae23647abc9d9fd0416629a4213a3882b101/xstream-1.4.10.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-core/2.0.0-beta.5/3e148ed3b247bc856e8e067349983bbd4f047698/powermock-core-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/io.mockk/mockk-agent-jvm/1.8.7/bd5d40b24f635d1736a731a751757fd8dada559c/mockk-agent-jvm-1.8.7.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-module-javaagent/2.0.0-beta.5/f0f3a1ace703bdfdd65f66de30e17476b95e39f2/powermock-module-javaagent-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-api-mockito2/2.0.0-beta.5/5aadd697a176794368d6750aafe6d7525ddbcef8/powermock-api-mockito2-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio/1.13.0/a9283170b7305c8d92d25aff02a6ab7e45d06cbe/okio-1.13.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.reactivestreams/reactive-streams/1.0.0/14b8c877d98005ba3941c9257cfe09f6ed0e0d74/reactive-streams-1.0.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/android.arch.core/common/1.0.0/a2d487452376193fc8c103dd2b9bd5f2b1b44563/common-1.0.0.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/recyclerview-v7-27.0.2.aar/2c7d60b8e21cd61058f074cfcd7982ac/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/recyclerview-v7-27.0.2.aar/2c7d60b8e21cd61058f074cfcd7982ac/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/glide-4.6.1.aar/d51db4e4ce5b419c3f99005f318cb51f/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-media-compat-27.0.2.aar/74cb3ebbfc887adccad27db14e4e674d/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-media-compat-27.0.2.aar/74cb3ebbfc887adccad27db14e4e674d/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-core-ui-27.0.2.aar/c802199f52f1956be81c09b15181603a/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/io.mockk/mockk-agent-api/1.8.7/3649e5c899ff965fe3280335ca861bdad309ac02/mockk-agent-api-1.8.7.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/annotations/4.6.1/278bafb890704b66a1d6a8a98d0790f940aa5a22/annotations-4.6.1.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.android.support/support-annotations/27.0.2/b9ef4342c934a1a8b107506273dc8061662a322/support-annotations-27.0.2.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/iconics-core-3.0.0.aar/6712b9ad6813ff7d193013bf0f47ade4/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/iconics-core-3.0.0.aar/6712b9ad6813ff7d193013bf0f47ade4/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/flexbox-0.3.2.aar/4636489e898af69d61f1e73224ab0929/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/flexbox-0.3.2.aar/4636489e898af69d61f1e73224ab0929/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-junit/2.0.0.0/221cf2b5aabedf8cd76534996caa21b283ea5d0/hamcrest-junit-2.0.0.0.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/support-fragment-27.0.2.aar/ffb48d997a54c5bbaa35c98a8602bfc5/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/rxandroid-2.0.1.aar/47c50c9202dd7894aa84344272332f2a/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.0.2.aar/d567cef2b0046b6b3bcf15f465f4a8c4/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.0.2.aar/d567cef2b0046b6b3bcf15f465f4a8c4/res:/Users/xyz/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-core/2.10.0/871efe6f2607d8c93dd25b8c1fa09851d4286dd6/mockito-core-2.10.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.8.8/965523f30c6994598e14fc1bbeab71d6e8910104/byte-buddy-agent-1.8.8.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/design-27.0.2.aar/69b7f18e65c1b596a7adf976322bbcb3/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/design-27.0.2.aar/69b7f18e65c1b596a7adf976322bbcb3/jars/classes.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.0.2.aar/24ef199235549deb501369df50ed9e9a/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.0.2.aar/24ef199235549deb501369df50ed9e9a/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/io.mockk/mockk-dsl/1.8.7/78783b4677170d0dc3f66ff8fc4faad2b8e198f3/mockk-dsl-1.8.7.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/adapter-rxjava2/2.3.0/f436637f9500ab5b8bc32afe556373180894b4a5/adapter-rxjava2-2.3.0.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-reflect/2.0.0-beta.5/4ea415348f15620783a1f26343d6732adfa86bc8/powermock-reflect-2.0.0-beta.5.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.2.61/772de03e12d932f489e41aef997d26c20a4ebee6/kotlin-stdlib-common-1.2.61.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/runtime-1.0.3.aar/0b2839a297936af1a68666ba8091ecdd/jars/classes.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/io.mockk/mockk/1.8.7/79c077c3704aa9e07605c70242a71d621b3a5f/mockk-1.8.7.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/xmlpull/xmlpull/1.1.3.1/2b8e230d2ab644e4ecaa94db7cdedbc40c805dfa/xmlpull-1.1.3.1.jar:/Users/xyz/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/common/1.0.3/7d7f60c4783872861222166f6164215f8951c7b1/common-1.0.3.jar:/Users/xyz/.gradle/caches/transforms-1/files-1.1/iconics-views-3.0.0.aar/97ad0c77dad0854a4cd37727b5579e0d/res:/Users/xyz/.gradle/caches/transforms-1/files-1.1/iconics-views-3.0.0.aar/97ad0c77dad0854a4cd37727b5579e0d/jars/classes.jar:/Users/xyz/Documents/androidapp/app/build/intermediates/sourceFolderJavaResources/debug:/Users/xyz/Documents/androidapp/app/build/generated/mockable-android-27.v3.jar" com.intellij.rt.execution.application.AppMainV2 com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 @w@/private/var/folders/7c/3s2ky2lx1pxb67bgfxr1cnsmxhg4_b/T/idea_working_dirs_junit.tmp @/private/var/folders/7c/3s2ky2lx1pxb67bgfxr1cnsmxhg4_b/T/idea_junit.tmp -socket51087
    
    java.lang.ExceptionInInitializerError
    at com.androidapp.movie.home.model.MoviesModelAdapterImplTest.setUp(MoviesModelAdapterImplTest.kt:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
    Caused by: java.lang.IllegalStateException: Error during attachment using: net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@66d2e7d9
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:377)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:351)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:319)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:305)
    at io.mockk.proxy.jvm.JvmMockKAgentFactory.initInstrumentation(JvmMockKAgentFactory.kt:106)
    at io.mockk.proxy.jvm.JvmMockKAgentFactory.init(JvmMockKAgentFactory.kt:31)
    at io.mockk.impl.JvmMockKGateway.<init>(JvmMockKGateway.kt:45)
    at io.mockk.impl.JvmMockKGateway.<clinit>(JvmMockKGateway.kt:163)
    ... 36 more
    Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at net.bytebuddy.agent.Attacher.install(Attacher.java:77)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:372)
    ... 43 more
    Caused by: java.lang.NullPointerException
    at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:182)
    ... 49 more
    
    
    Process finished with exit code 255
    

    I have installed java 10.0.2 but then i cannot use it in android studio, so i use the default jre/jdk path for android studio. Please assist. System: Mac OS Sierra

    Thanks

    question 
    opened by ghost 36
  • How to deal w/ module-info.java existing

    How to deal w/ module-info.java existing

    Hi

    We solved the bootstrap instrumentation in all JDKs. Now I want to dig more for JDK 9 - 12. As the module introduced in JDK, although most people don't use today, I want the plugin mechanism ready to go.

    I write a simple test, Main.java

    public class Main {
        public static void main(String[] args) throws IOException {
            URL obj = new URL("http://www.baidu.com");
            HttpURLConnection con = (HttpURLConnection)obj.openConnection();
    
            // optional default is GET
            con.setRequestMethod("GET");
            System.out.println(con.getRequestMethod());
    //        con.setChunkedStreamingMode(0);
    
            //add request header
    
            int responseCode = con.getResponseCode();
            System.out.println("Response Code : " + responseCode);
    
            BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();
    
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
    
            //print result
            System.out.println(response.toString());
        }
    }
    

    Empty module-info.java

    module JRE.test {
    }
    

    After I installed the agent, in JDK 9 -12, it shows the following error

    • Do bootstrap instrumentation
    ERROR 2019-08-01 14:24:38:322 main SkyWalkingAgent :  SkyWalking agent inject bootstrap instrumentation failure. Shutting down. 
    java.lang.UnsupportedOperationException: Could not access Unsafe class: sun.misc.Unsafe
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.loading.ClassInjector$UsingUnsafe$Dispatcher$Unavailable.initialize(ClassInjector.java:2033)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.loading.ClassInjector$UsingUnsafe.injectRaw(ClassInjector.java:1765)
    	at org.apache.skywalking.apm.agent.core.plugin.bootstrap.BootstrapInstrumentBoost.inject(BootstrapInstrumentBoost.java:102)
    	at org.apache.skywalking.apm.agent.SkyWalkingAgent.premain(SkyWalkingAgent.java:103)
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    	at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:500)
    	at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:512)
    
    • Do simple Main function instrumentation
    DEBUG 2019-08-01 14:26:48:650 main SkyWalkingAgent :  On Transformation class a.Main. 
    Exception in thread "main" java.lang.ExceptionInInitializerError
    Caused by: java.lang.reflect.InvocationTargetException
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    	at JRE.test/a.Main.<clinit>(Main.java)
    Caused by: java.lang.reflect.InvocationTargetException
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.Nexus.initialize(Nexus.java:137)
    	... 5 more
    Caused by: java.lang.UnsupportedOperationException: Cannot get package using reflection: sun.misc.Unsafe
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Initializable$Unavailable.getPackage(ClassInjector.java:418)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.injectRaw(ClassInjector.java:220)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.loading.ClassInjector$AbstractBase.inject(ClassInjector.java:112)
    	at org.apache.skywalking.apm.dependencies.net.bytebuddy.agent.builder.AgentBuilder$InitializationStrategy$SelfInjection$Dispatcher$InjectingInitializer.onLoad(AgentBuilder.java:3143)
    	... 10 more
    

    How should I avoid these? And make the plugin works if user turns module definition on?

    enhancement question 
    opened by wu-sheng 33
  • Byte Buddy agent with method interceptor and Groovy: java.lang.VerifyError method: <clinit> signature: ()V) Illegal type in constant pool

    Byte Buddy agent with method interceptor and Groovy: java.lang.VerifyError method: signature: ()V) Illegal type in constant pool

    Hi @raphw,

    do you have any experience with using Byte Buddy together with the Groovy language?

    I'm not yet sure what's the root cause, but as soon as I use the byte buddy agent (0.7.1) with a simple byte buddy method interceptor and intercept come Groovy code (2.4.5 on Java 8, "classic" dynamic Groovy code, not static Groovy code using @CompileStatic) I run occasionally into

    java.lang.VerifyError: (class: ch/concordia/cip/library/PowerBuilderAppsLib$controlWaitGetHandle, method: <clinit> signature: ()V) Illegal type in constant pool
    
        at java.lang.Class.getDeclaredConstructors0(Native Method)
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
        at java.lang.Class.getConstructor0(Class.java:3075)
        at java.lang.Class.getConstructor(Class.java:1825)
        at org.codehaus.groovy.reflection.ClassLoaderForClassArtifacts.defineClassAndGetConstructor(ClassLoaderForClassArtifacts.java:83)
        at org.codehaus.groovy.runtime.callsite.CallSiteGenerator.compileStaticMethod(CallSiteGenerator.java:246)
        at org.codehaus.groovy.reflection.CachedMethod.createStaticMetaMethodSite(CachedMethod.java:288)
        at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.createStaticMetaMethodSite(StaticMetaMethodSite.java:114)
        at groovy.lang.MetaClassImpl.createStaticSite(MetaClassImpl.java:3385)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallStaticSite(CallSiteArray.java:77)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:162)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
        at ch.concordia.cip.strukt.dos105.search.DOS105SearchWindow.selectNummernTab$original$Bmy4nhh3(DOS105SearchWindow.groovy:28)
        at ch.concordia.cip.strukt.dos105.search.DOS105SearchWindow.selectNummernTab$original$Bmy4nhh3$accessor$pJ0AcOyc(DOS105SearchWindow.groovy)
        at ch.concordia.cip.strukt.dos105.search.DOS105SearchWindow$auxiliary$nozMrD9b.call(Unknown Source)
        at ch.concordia.cip.testcases.RunlogAgent$LogAndInvokeMethodInterceptor.logAndInvoke(RunlogAgent.java:65)
        at ch.concordia.cip.strukt.dos105.search.DOS105SearchWindow.selectNummernTab(DOS105SearchWindow.groovy)
        at ch.concordia.cip.keywords.Dossier.dossierNrLesen$original$dq3Q7cin(Dossier.java:23)
        at ch.concordia.cip.keywords.Dossier.dossierNrLesen$original$dq3Q7cin$accessor$ZWGwpIx3(Dossier.java)
        at ch.concordia.cip.keywords.Dossier$auxiliary$BfbH49fM.call(Unknown Source)
        at ch.concordia.cip.testcases.RunlogAgent$LogAndInvokeMethodInterceptor.logAndInvoke(RunlogAgent.java:65)
        at ch.concordia.cip.keywords.Dossier.dossierNrLesen(Dossier.java)
        at ch.concordia.cip.testcases.JUnitTestCaseDossier1.testVolldaten1(JUnitTestCaseDossier1.java:36)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    

    I guess it's about the fact, that Groovy does some code generation at runtime, like this part of the stacktrace shows

        at org.codehaus.groovy.reflection.ClassLoaderForClassArtifacts.defineClassAndGetConstructor(ClassLoaderForClassArtifacts.j
        at org.codehaus.groovy.runtime.callsite.CallSiteGenerator.compileStaticMethod(CallSiteGenerator.java:246)                 
        at org.codehaus.groovy.reflection.CachedMethod.createStaticMetaMethodSite(CachedMethod.java:288)                          
        at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.createStaticMetaMethodSite(StaticMetaMethodSite.java:114)    
    

    Maybe there are some turbuluences when Groovy and Byte Buddy?

    The good news is, that as soon as I use Groovy's @CompileStatic on the target class, the issue is gone.

    The bad news is (for me), that this is not always possible.

    Thanks for your insights!

    Best regards from Lucerne (Switzerland), Peti

    bug enhancement question 
    opened by Petikoch 32
  • Unable to install agent with IntelliJ bundled SDK on MacOS

    Unable to install agent with IntelliJ bundled SDK on MacOS

    When using Bytebuddy within IntelliJ and bundled Java 11 on MacOS it caused the following exception:

    Caused by: java.io.IOException: Cannot run program ""/Applications/IntelliJ IDEA.app/Contents/jbr/Contents/Home/bin/java"": error=2, No such file or directory
        at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
        at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
        at net.bytebuddy.agent.ByteBuddyAgent.installExternal(ByteBuddyAgent.java:669)
        at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:601)
        ... 102 more
    

    The culprit seems to be ByteBuddyAgent.java#L664

    Additional Info:

    IntelliJ Version 2019.3.1 (IU-193.5662.53)
    bytebuddy 1.9.16
    
    bug 
    opened by bitbrain 31
  • How to add okhttp custom interceptor at runtime using bytebuddy?

    How to add okhttp custom interceptor at runtime using bytebuddy?

    I want to add my interceptor at runtime in okhttpclient, I am making Agent using bytebuddy in premain class. And i am trying to intercept the constructor of "okhttp3.OkHttpClient.Builder" to add my interceptor in the interceptors list. But the problem is that the type() method is unable to find my class, I've tried different ways for eg: ElementMatchers .is(), .nameStartsWith(), .nameContains(), named() etc. but couldn't find the class.

    I know that okhttp uses Kotlin & java adds $ in the namespace to invoke some methods, so for my case i changed it to "okhttp3.OkHttpClient$Builder", but again it was not finding the matching class.

    I also want to know my approach that am i doing the right way to add the custom interceptor.

    Agent:

    public static void premain(String arg, Instrumentation instrumentation) {
    
        new AgentBuilder.Default()           
              .type(ElementMatchers.named("okhttp3.OkHttpClient.Builder"))
              .transform((builder, typeDescription, classLoader, javaModule, protectionDomain) -> {
                        System.out.println("Transformer: adding custom okhttpinterceptor using agent: " + typeDescription.getName());
                        return builder.constructor(ElementMatchers.takesArgument(1, OkHttpClient.class))
                                .intercept(MethodDelegation.to(ConstructorInterceptor.class));
                    })
              .installOn(instrumentation);
        }
    

    Constructor Interceptor:

    public class ConstructorInterceptor {
    
             public static void doProceed(
                @SuperCall
                Callable<?> client,
                @Argument(0)
                OkHttpClient okHttpClient, @Origin String method) throws Exception {
    
            System.out.println("Constructor Interceptor was called for: " + method);
            client.call();
            okHttpClient.interceptors().add(new HttpInterceptor());
        }
    }
    

    HttpInterceptor:

    public class HttpInterceptor implements Interceptor{
    
          @NotNull
          @Override
          public Response intercept(@NotNull Interceptor.Chain chain) throws IOException {
            Request request = chain.request();
    
            String reqBody = getRequestBody(request);
    
            System.out.println("Inside HttpInterceptor before next()");
    
            Response response = chain.proceed(request);
    
            System.out.println("Inside HttpInterceptor after next()");
    
            return response;
        }
     }
    
    question 
    opened by gouravkrosx 27
  • [Question] Is redefine suitable for new class generated, which is used as a bootstrap class interceptor?

    [Question] Is redefine suitable for new class generated, which is used as a bootstrap class interceptor?

    I am working on adding bootstrap instrumentation to SkyWalking these days. The interceptor works, the last piece of POC is accessing the same TracingContext/ContextManger/...(several tracing core) which are loaded in ApplicationClassLoader.

    Do I have to have ApplicationClassLoader or agent Classloader through the bootstrap interceptor? The following one fails, of course

    package org.apache.skywalking.apm.plugin.jre.httpurlconnection;
    
    import java.lang.reflect.Method;
    import java.util.concurrent.Callable;
    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;
    import org.apache.skywalking.apm.agent.core.context.ContextManager;
    import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
    
    /**
     * @author wusheng
     */
    public class Interceptor {
        /**
         * Intercept the target instance method.
         *
         * @param obj target class instance.
         * @param allArguments all method arguments
         * @param method method description.
         * @param zuper the origin call ref.
         * @return the return value of target instance method.
         * @throws Exception only throw exception because of zuper.call() or unexpected exception in sky-walking ( This is a
         * bug, if anything triggers this condition ).
         */
        @RuntimeType
        public static Object intercept(@This Object obj,
            @AllArguments Object[] allArguments,
            @SuperCall Callable<?> zuper,
            @Origin Method method
        ) throws Throwable {
            AbstractSpan abc = ContextManager.createLocalSpan("abc");
            Object result = zuper.call();
            ContextManager.stopSpan(abc);
            return result;
        }
    }
    
    question 
    opened by wu-sheng 26
  • Please comply with ASM license when re-distributing ASM

    Please comply with ASM license when re-distributing ASM

    ASM license specifies that Redistributions of source code must retain the ... copyright notice

    I see that byte-buddy-1.10.0.jar bundles ASM under byte-buddy-1.10.0.jar/uzip://net/bytebuddy/jar path, however it fails to retain the relevant copyright notice.

    Would you please comply with ASM license? (see https://gitlab.ow2.org/asm/asm/blob/e246de13a995837bc88777aca47f141d9bcbfc01/LICENSE.txt )

    Thanks.

    PS. Here's relevant ASM issue: https://gitlab.ow2.org/asm/asm/issues/317880

    documentation build 
    opened by vlsi 23
  • Intercepting in Android

    Intercepting in Android

    Hi, I would like to try the byte-buddy on Android https://github.com/raphw/byte-buddy/tree/master/byte-buddy-android

    I could run the above example, however I'm wonder if there is an option to wrap existing method with some logic or replace existing implementation. If yes - an example will be great.

    Thanks

    question 
    opened by moshere 2
  • Reduce Gradle plugin boilerplate

    Reduce Gradle plugin boilerplate

    Assuming that I have a Byte Buddy build plugin with a valid META-INF/net.bytebuddy/build.plugins file, here is what the current boilerplate looks like for using said plugin in another project using Gradle (I am using plain Java, not Android):

    plugins {
    	id "net.bytebuddy.byte-buddy-gradle-plugin" version "1.12.20"
    }
    
    configurations.register("byteBuddy")
    
    dependencies {
    	byteBuddy "org.example:my-byte-buddy-plugin:1.0.0-SNAPSHOT"
    }
    
    byteBuddy {
    	discoverySet = configurations.byteBuddy
    	transformation {
    		pluginName = "org.example.MyByteBuddyPlugin"
    	}
    }
    

    If #1378 is fixed, this can be reduced to:

    plugins {
    	id "net.bytebuddy.byte-buddy-gradle-plugin" version "1.12.20"
    }
    
    configurations.register("byteBuddy")
    
    dependencies {
    	byteBuddy "org.example:my-byte-buddy-plugin:1.0.0-SNAPSHOT"
    }
    
    byteBuddy {
    	discoverySet = configurations.byteBuddy
    }
    

    Now I'm wondering, wouldn't it be nice if we could reduce it to:

    plugins {
    	id "net.bytebuddy.byte-buddy-gradle-plugin" version "1.12.20"
    }
    
    dependencies {
    	byteBuddy "org.example:my-byte-buddy-plugin:1.0.0-SNAPSHOT"
    }
    

    That is to say, I would like the byte-buddy-gradle-plugin to automatically create the byteBuddy configuration and use it as the default discoverySet. Curiously, this feature seems to already exist for Android (but not for plain Java): https://github.com/raphw/byte-buddy/blob/d4b5cdbed4a94fccfe457daf4913dccc8c02a175/byte-buddy-gradle-plugin/android-plugin/README.md?plain=1#L7-L8

    enhancement 
    opened by 0dinD 6
  • Automatic plugin discovery doesn't work when using Gradle

    Automatic plugin discovery doesn't work when using Gradle

    When using the byte-buddy-gradle-plugin (I am using plain Java, not Android), it seems like the automatic plugin discovery mentioned here doesn't work: https://github.com/raphw/byte-buddy/blob/d4b5cdbed4a94fccfe457daf4913dccc8c02a175/byte-buddy-gradle-plugin/README.md?plain=1#L28

    By "doesn't work" I mean that nothing happens, the plugin (which is in the discoverySet) and its transformations are not applied. If I run Gradle with the --debug flag, I do find this:

    [DEBUG] [org.gradle.api.Project] Not configuring task for source set 'main' as no transformations are defined
    

    Which I think comes from here: https://github.com/raphw/byte-buddy/blob/d4b5cdbed4a94fccfe457daf4913dccc8c02a175/byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/AbstractByteBuddyTaskConfiguration.java#L71

    But I thought the whole point of the automatic discovery was that I shouldn't have to specify any transformations explicitly? So it seems like there is a bug in the byte-buddy-gradle-plugin?

    To be clear, everything works as expected if I manually specify a transformations { pluginName = "..." } entry, but I'd like to avoid it since this is already declared in the META-INF/net.bytebuddy/build.plugins file. It's also worth mentioning that I tried the same thing using byte-buddy-maven-plugin, where automatic plugin discovery worked like a charm without having to specify any explicit transformation entries.

    bug 
    opened by 0dinD 3
  • Adding a method invocation to a method body without using substitution?

    Adding a method invocation to a method body without using substitution?

    How can I just add a method invocation to a method body (without the method invocation I want to include in the method body being the substitute for something in the method body)? Thanks.

    question 
    opened by orange0rca 3
  • IllegalStateException when running a web Application with a bytebuddy java agent

    IllegalStateException when running a web Application with a bytebuddy java agent

    When running a web application built using dropwizard and lombok, the following error is noticed for multiple classes.

    [Byte Buddy] ERROR com.xxxx.xxxx.xxx.x.xxxxRequest [sun.misc.Launcher$AppClassLoader@18b4aac2, null, loaded=false] java.lang.IllegalStateException: Unexpected type reference on method: 19 at net.bytebuddy.pool.TypePool$Default$TypeExtractor$MethodExtractor.visitTypeAnnotation(TypePool.java:8198) at net.bytebuddy.jar.asm.ClassReader.readMethod(ClassReader.java:1213) at net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:679) at net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:391) at net.bytebuddy.pool.TypePool$Default.parse(TypePool.java:1176) at net.bytebuddy.pool.TypePool$Default.doDescribe(TypePool.java:1160) at net.bytebuddy.pool.TypePool$Default$WithLazyResolution.access$401(TypePool.java:1240) at net.bytebuddy.pool.TypePool$Default$WithLazyResolution.doResolve(TypePool.java:1338) at net.bytebuddy.pool.TypePool$Default$WithLazyResolution$LazyTypeDescription.delegate(TypePool.java:1407) at net.bytebuddy.description.type.TypeDescription$AbstractBase$OfSimpleType$WithDelegation.getDeclaredAnnotations(TypeDescription.java:8101) at net.bytebuddy.matcher.DeclaringAnnotationMatcher.matches(DeclaringAnnotationMatcher.java:48) at net.bytebuddy.matcher.DeclaringAnnotationMatcher.matches(DeclaringAnnotationMatcher.java:27) at net.bytebuddy.agent.builder.AgentBuilder$RawMatcher$ForElementMatchers.matches(AgentBuilder.java:1292) at net.bytebuddy.agent.builder.AgentBuilder$Default$Transformation$Simple.matches(AgentBuilder.java:9983) at net.bytebuddy.agent.builder.AgentBuilder$Default$Transformation$Simple.resolve(AgentBuilder.java:9996) at net.bytebuddy.agent.builder.AgentBuilder$Default$Transformation$Compound.resolve(AgentBuilder.java:10252) at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.resolve(AgentBuilder.java:10584) at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:10551) at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:10514) at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1500(AgentBuilder.java:10280) at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:10889) at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:10836) at java.security.AccessController.doPrivileged(Native Method) at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:10437) at sun.instrument.TransformerManager.transform(TransformerManager.java:188) at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:756) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) at java.net.URLClassLoader.access$100(URLClassLoader.java:74) at java.net.URLClassLoader$1.run(URLClassLoader.java:369) at java.net.URLClassLoader$1.run(URLClassLoader.java:363) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:362) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) at java.lang.ClassLoader.loadClass(ClassLoader.java:351) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:756) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) at java.net.URLClassLoader.access$100(URLClassLoader.java:74) at java.net.URLClassLoader$1.run(URLClassLoader.java:369) at java.net.URLClassLoader$1.run(URLClassLoader.java:363) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:362) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) at java.lang.ClassLoader.loadClass(ClassLoader.java:351) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:756) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) at java.net.URLClassLoader.access$100(URLClassLoader.java:74) at java.net.URLClassLoader$1.run(URLClassLoader.java:369) at java.net.URLClassLoader$1.run(URLClassLoader.java:363) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:362) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) at java.lang.ClassLoader.loadClass(ClassLoader.java:351) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at ru.vyarus.dropwizard.guice.module.installer.scanner.util.OReflectionHelper.findClasses(OReflectionHelper.java:124) at ru.vyarus.dropwizard.guice.module.installer.scanner.util.OReflectionHelper.findClasses(OReflectionHelper.java:121) at ru.vyarus.dropwizard.guice.module.installer.scanner.util.OReflectionHelper.findClasses(OReflectionHelper.java:121) at ru.vyarus.dropwizard.guice.module.installer.scanner.util.OReflectionHelper.findClasses(OReflectionHelper.java:121) at ru.vyarus.dropwizard.guice.module.installer.scanner.util.OReflectionHelper.findClasses(OReflectionHelper.java:121) at ru.vyarus.dropwizard.guice.module.installer.scanner.util.OReflectionHelper.getClassesFor(OReflectionHelper.java:79) at ru.vyarus.dropwizard.guice.module.installer.scanner.ClasspathScanner.performScan(ClasspathScanner.java:108) at ru.vyarus.dropwizard.guice.module.installer.scanner.ClasspathScanner.(ClasspathScanner.java:50) at ru.vyarus.dropwizard.guice.module.GuiceyInitializer.(GuiceyInitializer.java:77) at ru.vyarus.dropwizard.guice.GuiceBundle.initialize(GuiceBundle.java:116) at io.dropwizard.setup.Bootstrap.addBundle(Bootstrap.java:134) at com.xxxx.xxxx.xxx.ManagerApplication.initialize(ManagerApplication.java:67) at io.dropwizard.Application.run(Application.java:88) at com.xxxx.xxxx.xxx.ManagerApplication.main(ManagerApplication.java:55)

    Bytebuddy version is 1.12.6. What would be causing this issues ?

    I tested the same agent on an application with one API call and nothing else and everything works.

    question 
    opened by avinash-fk 1
  • unable to target java.sql.DriverManager class

    unable to target java.sql.DriverManager class

    I was trying to intercept registerDriver method in java.sql.DriverManager class by using Bytebuddy's agent in premain.

          new AgentBuilder.Default(new ByteBuddy().with(TypeValidation.DISABLED))
           .with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
           .with(AgentBuilder.Listener.StreamWriting.toSystemOut())
           .type(named("java.sql.DriverManager"))
           .transform((builder, typeDescription, classLoader, javaModule, protectionDomain) -> {
                 System.out.println("INSIDE REGISTER DRIVER TRANSFORMER !!!! ");
                 try {
                        return builder.method(named("registerDriver").and(takesArguments(2)))
                       .intercept(FixedValue.value(new KDriver()));
                      } catch (SQLException e) {
                            throw new RuntimeException(e);
                        }                    
            
              .intercept(MethodDelegation.to(TypePool.Default.ofSystemLoader()
             .describe("io.keploy.advice.ksql.RegisterDriverManagerAdvice").resolve()));
                    }).installOn(instrumentation);
    

    But i was unable to locate the DriverManager Class, when i used Listener i found that there is not a single class of java.sql package it was showing. Any help would be appreciated.

    question 
    opened by Sarthak160 4
Releases(byte-buddy-1.12.20)
  • byte-buddy-1.12.20(Dec 15, 2022)

    • Avoid stack overflow error when type variable cannot be resolve during error message generation.
    • Allow dumping error message to file when remote attach fails.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.19(Nov 17, 2022)

    • Avoid possible lock through circular class loading of TypeDescription subtypes.
    • Avoid access error when using unsafe API on Java 17 with an active security manager.
    • Close URL class loader used in Gradle plugin.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.18(Oct 13, 2022)

    • Allow writing to field from enter Advice in constructor, as byte code allows it.
    • Refactor Android plugin processor to avoid skipping local classes.
    • Improve staleness filter for Maven plugin.
    • Fix incorrect resolution of custom bound invokedynamic values in Advice.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.17(Sep 22, 2022)

  • byte-buddy-1.12.16(Sep 8, 2022)

  • byte-buddy-1.12.15(Sep 8, 2022)

    • Introduce ClassVisitorFactory which allows to translate to and from class wrappers in a different ASM namespace.
    • Allow builders to change to ClassVisitors.
    • Add support for Android instrumentation from Gradle plugin.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.14(Aug 22, 2022)

    • Add wrap method to DynamicType.Builder that allows for the representation of a dynamic type via a ClassVisitor.
    • Add ClassVisitorFactory that allows to translate between Byte Buddy's, the original, or other shaded representations of ASM.
    • Fix visibility check for types in the default package.
    • Return correct value for types in the default package.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.13(Aug 1, 2022)

    • Avoid duplicate application of Byte Buddy Maven plugin.
    • Allow for class path discovery of Plugins when using Maven.
    • Fix build cache when using Byte Buddy Gradle plugin.
    • Allow Plugins to define new types prior to transformation.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.12(Jun 25, 2022)

    • Use correct annotation in Byte Buddy Gradle plugin.
    • Correctly resolve generified anonymous/local types that are declared within a method.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.11(Jun 23, 2022)

    • Remove use of thread-local to guarantee Loom compatibility.
    • Allow usage of byte-buddy-parent as BOM for imports.
    • Add convenience for Maven to disable type validation on entry point.
    • Allow Gradle plugin to consume pluginName property and discoverySet to only load plugins in the plugin class loader.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.10(May 1, 2022)

    • Correctly resolve temporary folder, if custom folder is set, on Linux during emulated attach.
    • Attempt guessing if Graal automatic configuration agent for native image is run.
    • Avoid hard-coded dependencies to classes of java.management module.
    • Do not include OSGi info in Byte Buddy source module.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.9(Apr 7, 2022)

    • Add support for Java 19.
    • Add basic support for Graal native image.
    • Add option for strongly referenced cache keys.
    • Reduce access requirements for fields from Advice.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.8(Feb 10, 2022)

    • Make Step type in MemberSubstitution public as intended.
    • Add factory that uses ArrayDeque instead of LinkedList if the used JVM supports it (Java 6+).
    • Fix resolution of internal names for arrays in TypeReferenceAdjustment.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.7(Jan 15, 2022)

    • Adjust warm-up API to return warmed-up byte code.
    • Check release property in Byte Buddy Maven plugin.
    • Propagate exception from Byte Buddy's class file transformer to improve wrapping behavior.
    • Avoid loading of ElementType when checking compatibility as the current VM might not provide all constants.
    • Allow for disabling stack adjustment as it might not always be possible.
    • Make stack adjustment more robust when goto targets contain stack values.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.6(Dec 20, 2021)

  • byte-buddy-1.12.5(Dec 16, 2021)

    • Add alias annotations to avoid compilation warnings for optional findbugs dependency.
    • Adjust HashCodeEqualsPlugin to allow for inclusion of custom annotation type on equals method parameter.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.4(Dec 15, 2021)

    • Make paths in Gradle plugin relative and therewith cachable.
    • Add explicit check for empty or non-existent source folder to Maven and Gradle plugins.
    • Add support for modules when accessing system class loader for Nexus or Installer.
    • Add nullability annotations to all type members which are nullable and declare non-nullability the default.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.3(Dec 2, 2021)

    • Move configuration for Java version to extension and avoid implicit configuration during task execution to allow for using a configuration cache.
    • Make fail last the alternative to fail fast instead of not failing the build. Enable fail fast by default in the Gradle plugin.
    • Use instrumented type in MemberSubstitution to include newly added properties in its description.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.2(Nov 22, 2021)

    • Improve error message when class file version is not supported.
    • Avoid duplication of fields to store auxiliary objects.
    • Fix Gradle plugin to be skipped when input files are empty.
    • Resolve dynamic bootstrap constant type correctly.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.1(Nov 9, 2021)

    • Fix binary incompatibility in BaseNameResolver for suffixing naming strategy.
    • Introduce caller sensitive base name resolver for suffixing naming strategies and use it as default if Graal native image property is discovered.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.12.0(Nov 5, 2021)

    • Introduce detection for Graal native image execution.
    • Correctly resolve interface implementations in revers order when compiling method graph.
    • Adjust lambda instrumentation strategy to support Java 17.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.11.22(Oct 29, 2021)

  • byte-buddy-1.11.21(Oct 18, 2021)

    • Allow Advice.PostProcessor to emitt frames.
    • Add possibility for Advice.AssignReturned to suppress exceptions.
    • Add frame when rebasing constructors to avoid breakage if frames are assumed prior to super constructor call.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.11.20(Oct 11, 2021)

    • Add option for AsScalar annotation to assign default value instead of ignoring it.
    • Add transform-runtime goal to Byte Buddy Mojo to allow for running plugins with runtime class path included.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.11.19(Oct 5, 2021)

    • Add Advice.AssignReturned post processor to allow for assigning values from Advice that uses delegation rather than inlining.
    • Allow for declaring Advice.Local values from both enter and exit advice.
    • Add option for using runtime class path rather than only compile scope from Byte Buddy Maven plugin.
    • Avoid loading of annotation proxies within Byte Buddy's internal API.
    • Add plugin to add Java Repeatable annotations without requiring a JDK 8+.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.11.18(Sep 22, 2021)

    • Avoid binary incompatibility due to signature change by reintroducing method overload.
    • Use plugin to add annotations for dispatcher methods to avoid breakage when using obfuscators.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.11.17(Sep 22, 2021)

    • Better error message upon attachment failure due to overridden attach socket.
    • Retain label order for instructions in Advice to avoid incorrect offsets in stack map frames.
    • Change MethodGraph.Compiler API to accept generic types.
    • Add plugin to add Proxied annotations to all proxied methods of a dispatcher. This avoids problems in obfuscators.
    • Fix resolution of type initializer in a Nexus.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.11.16(Sep 18, 2021)

    • Avoid naming conflicts when adding super and default method delegation for the same method using MethodDelegation.
    • Fix module visibility for Invoker to avoid breakage if Byte Buddy is shaded into another module with different package exports.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.11.15(Sep 2, 2021)

    • Add net.bytebuddy prefix to Byte Buddy specific privileges.
    • Rework JavaDispatcher to require specific privilege but use Byte Buddy's protection domain for dispatchers, once acquired.
    Source code(tar.gz)
    Source code(zip)
  • byte-buddy-1.11.14(Aug 31, 2021)

    • Adjust InvocationHandlerAdapter to use null for methods without parameters as specified by contract.
    • Offer option to use null for MethodDelegation and Advice if method has no parameters.
    • Add method to seal unsealed class loaders after the fact.
    • Use correct type for resolving security manager method in ByteBuddyAgent.
    Source code(tar.gz)
    Source code(zip)
Owner
Rafael Winterhalter
software consultant who likes static types
Rafael Winterhalter
Obsi-bot: the next generation discord utility bot 🔥

obsi-bot obsi-bot is the next generation discord utility bot. It is developed in Kotlin using kordex and kord Help me translating Feel free to help me

mooziii 2 Nov 7, 2022
Ask Permission - Simple RunTime permission manager

Ask Permission https://kishanjvaghela.github.io/Ask-Permission/ Simple RunTime permission manager How to use Add url to your gradle file compile 'com.

Kishan Vaghela 77 Nov 18, 2022
📱 objection - runtime mobile exploration

objection is a runtime mobile exploration toolkit, powered by Frida, built to help you assess the security posture of your mobile applications, without needing a jailbreak.

SensePost 5.6k Jan 5, 2023
WebSocket & WAMP in Java for Android and Java 8

Autobahn|Java Client library providing WAMP on Java 8 (Netty) and Android, plus (secure) WebSocket for Android. Autobahn|Java is a subproject of the A

Crossbar.io 1.5k Dec 9, 2022
General purpose utilities and hash functions for Android and Java (aka java-common)

Essentials Essentials are a collection of general-purpose classes we found useful in many occasions. Beats standard Java API performance, e.g. LongHas

Markus Junginger 1.4k Dec 29, 2022
WebSocket & WAMP in Java for Android and Java 8

Autobahn|Java Client library providing WAMP on Java 8 (Netty) and Android, plus (secure) WebSocket for Android. Autobahn|Java is a subproject of the A

Crossbar.io 1.5k Dec 9, 2022
General purpose utilities and hash functions for Android and Java (aka java-common)

Essentials Essentials are a collection of general-purpose classes we found useful in many occasions. Beats standard Java API performance, e.g. LongHas

Markus Junginger 1.4k Dec 29, 2022
Trail is a simple logging system for Java and Android. Create logs using the same API and the library will detect automatically in which platform the code is running.

Trail Trail is a simple logging system for Java and Android. Create logs using the same API and the library will detect automatically in which platfor

Mauricio Togneri 13 Aug 29, 2022
A low intrusive, configurable android library that converts layout XML files into Java code to improve performance

qxml English 一个低侵入,可配置的 Android 库,用于将 layout xml 文件转换为 Java 代码以提高性能。 与X2C的对比 X2C: 使用注解处理器生成View类,使用时需要在类中添加注解,并替换setContentView方法,侵入性较强; 对于布局属性的支持不够完美

null 74 Oct 6, 2022
Java implementation of a Disk-based LRU cache which specifically targets Android compatibility.

Disk LRU Cache A cache that uses a bounded amount of space on a filesystem. Each cache entry has a string key and a fixed number of values. Each key m

Jake Wharton 5.7k Dec 31, 2022
a simple cache for android and java

ASimpleCache ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。 1、它可以缓存什么东西? 普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 b

Michael Yang 3.7k Dec 14, 2022
gRPC and protocol buffers for Android, Kotlin, and Java.

Wire “A man got to have a code!” - Omar Little See the project website for documentation and APIs. As our teams and programs grow, the variety and vol

Square 3.9k Dec 31, 2022
A lightning fast, transactional, file-based FIFO for Android and Java.

Tape by Square, Inc. Tape is a collection of queue-related classes for Android and Java. QueueFile is a lightning-fast, transactional, file-based FIFO

Square 2.4k Dec 30, 2022
UPnP/DLNA library for Java and Android

Cling EOL: This project is no longer actively maintained, code may be outdated. If you are interested in maintaining and developing this project, comm

4th Line 1.6k Jan 4, 2023
Apk parser for java

APK parser lib, for decoding binary XML files, getting APK meta info. Table of Contents Features Get APK-parser Usage 1. APK Info 2. Get Binary XML an

Hsiafan 1.1k Jan 2, 2023
Error handling library for Android and Java

ErrorHandler Error handling library for Android and Java Encapsulate error handling logic into objects that adhere to configurable defaults. Then pass

null 237 Dec 29, 2022
Apk parser for java

APK parser lib, for decoding binary XML files, getting APK meta info. Table of Contents Features Get APK-parser Usage 1. APK Info 2. Get Binary XML an

Hsiafan 1.1k Dec 18, 2022
Multiplaform kotlin library for calculating text differences. Based on java-diff-utils, supports JVM, JS and native targets.

kotlin-multiplatform-diff This is a port of java-diff-utils to kotlin with multiplatform support. All credit for the implementation goes to original a

Peter Trifanov 51 Jan 3, 2023
java.io.File compatible SAF library

DocumentFileX java.io.File compatible SAF implementation Tired of SAF bullshits? Implement SAF with ease! This library is in alpha stage. Most feature

null 24 Aug 25, 2022