How to explicitly invoke default method simply, without reflection and dynamic Proxy? - java

I was reading about default methods in Java 8 and I got stuck in one thing - is there a way to invoke default method from interface without implementing it, or using dynamic Proxy? By using just a simple way, like in following methods:
interface DefaultTestInterface{
default void method1(){
//default method
}
}
class ImplementingClass implements DefaultTestInterface{
public void method1(){
//default method invocation in implementing method
DefaultTestInterface.super.method1();
}
void method2(){
//default method invocation in implementing class
DefaultTestInterface.super.method1();
}
}
public class Main {
public static void main(String[] args) {
//is there any way to simply invoke default method without using proxy and reflection?
}
}
I read similar questions, but the first was connected only with invocation in implementing method, and two others was connected with dynamic Proxy using reflection and reflection.
Those solutions are quite complicated and I am wondering if there is simpler way of doing it. I also read those articles, but I didn't found solution for my problem. I would be grateful for any help.

If the interface has only one method, or all its methods have default implementations, all you need to do is creating an anonymous implementation that does not implement the method that you wish to call:
(new DefaultTestInterface() {}).method1();
Demo.

Related

How to define AnswersWithDelay for a void returning method

So, I want to mimic in Mockito a method that is making a network call and is waiting for it to complete before returning. I found this nice answer here: https://stackoverflow.com/a/50530261/4433222 that suggests using AnswersWithDelay.
Issue is though that I struggle to define a method's behavior for a method that returns void. AnswersWithDelays constructor requires a parameter of Answer<Object> type, and I wasn't able to find how to set it as void. Any clues?
First of all, AnswersWithDelay is an internal class of Mockito. So you should not use it directly. Instances of this class are supposed to be created by using the factory methods in the public AdditionalAnswers class.
So all you need is
doAnswer(AdditionalAnswers.answersWithDelay(delay, invocation -> null)).when(mockObject).doSomething();
Based on this answer, with a draft test class.
#ExtendWith(SpringExtension.class)
public class MockDelayVoidTest {
#MockBean
private Object myMock;
void test(){
Mockito.doAnswer(AdditionalAnswers.answersWithDelay(1000, invocationOnMock -> {
//here you can customize the behavior of your mock method
return null;}))
.when(myMock).toString();
}
}
Another way may be,
Mockito.doAnswer(invocation -> {
TimeUnit.SECONDS.sleep(5);
return null;
}).when(mock).doSomething();

Is it possible to use JMockit's Deencapsulation API to exchange method implementation?

So, basically, a there is some poor code that I cannot change that needs to be tested. Traditionally, you inject your mocked dependencies, but with this code, I cannot do so, because there are no setter methods. Worse, the function I need to test calls a bunch of static factory methods-I can't just use the MockUp strategy to swap out the implementation there, because there is no class instance to be injected at all.
In C/++, you can retrieve a pointer to a function and know it's type by it's signature. If you changed the pointer, then you could potentially change how the stack was constructed by the compiler and you could pass function's around and all that Jazz.
Is there a way to use the Deencapsulation API to replace a static method implementation? Using this, I could write my own class, descend from the traditional, but return mocked objects in order that dependency injection still be achieved?
public class TestedClass {
public static void testedMethod() {
UnMockableType instanceVariable =
UnInjectableFactory.staticFactoryConstructor();
instanceVariable.preventControlFlowInfluenceThroughMocking();
}
}
Easy enough:
#Test
public void exampleTestUsingAMockUp()
{
new MockUp<UnMockableType>() {
#Mock
void preventControlFlowInfluenceThroughMocking() {}
};
TestedClass.testedMethod();
}
Above, UnInjectableFactory isn't mocked because it doesn't need to be (assuming it simply instantiates/recovers an UnMockableType).
It could also be done with #Mocked and the Expectations API.

How to "proxy" a method in Java

First off, I'm not sure how to best word my solution so if I seem to be babbling at times then please consider this.
There is an interface in a library I wish to modify without touching the physical code,
public interface ProxiedPlayer {
// .. other code
public void setPermission(String permission, boolean state);
}
I have written a third party library for handling permissions and having to hook into my API to edit permissions may be a step some developers do not want to take. So I ask that when setPermission is called is it possible to have it invoke my invoke the appropriate method in my library that will handle permission setting whilst ignoring the pre-programmed code or not?
Here is the full interface I am attempting to proxy.
I have looked into the Java Proxy class but it seems you need an instance of the object you're trying to proxy in the first place. Given that the method can be called any time I do not believe this to be my solution but will happily stand corrected.
I do not have control over instantiation of classes implementing the ProxiedPlayer interface.
EDIT: Ignorant me, there several events that I can subscribe to where it is possible to get an instance of the player, would this be the appropriate place to attempt to proxy the method? One of these events is fired when a player joins the server and getting the instance of the player is possible.
Would the Proxy code need to be called for every instance of the ProxiedPlayer interface or is it possible to simply proxy every invocation of the method in an easier way?
My library is a plugin loaded after everything else that is essential has finished loading.
Edit #2:
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class InvocationProxy implements InvocationHandler {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ProxiedPlayer player = (ProxiedPlayer) proxy;
if(method.getName().equals("setPermission")) {
// Call my code here?
}
return method.invoke(player, args);
}
}
Would something along the lines of what I have above work or am I barking up the wrong tree entirely?
If you do not want to touch the original source, then you only solve this problem by using a Java agent that redefines any class that implements the ProxiedPlayer interface to enforce your security check before calling the actual method. AspectJ together with a load-time-weaving agent was already mentioned as a possible solution for this but you can also implement a pure Java solution using my library Byte Buddy:
public class InterceptionAgent {
public static void premain(String arguments,
Instrumentation instrumentation) {
new AgentBuilder.Default()
.rebase(isSubtypeOf(ProxiedPlayer.class))
.transform(new AgentBuilder.Transformer() {
#Override
public DynamicType.Builder transform(DynamicType.Builder builder) {
return builder.method(named("setPermission"))
.intercept(MethodDelegation.to(MyInterceptor.class)
.andThen(SuperMethodInvocation.INSTANCE));
}
}).installOn(instrumentation);
}
}
With this agent, you more or less specify that you want to redefine any class that is a subtype of ProxiedPlayer to redefine (any) method named setPermisson in order to call a MyInterceptor (that would be your code) and to subsequently call the original implementation.
Note that the suggested implementation assumes that all classes implementing ProxiedPlayer implement the method of this interface and that there is only a single method of this signature. This might be too simple but it shows what direction to go.

Generic method invocation using annotations

I am creating a web application and I am injecting a SystemManager interface in it. All of my business logic resides behind it and pages just have to request data from it. I would like to create a generic implementation which would get a method signature and based on the annotation it would invoke the correct method in the system.
The implementation of this interface acts like a facade pattern - it just calls methods on different objects.
The current implementation is
SystemManager.java
void executeA();
void executeB();
SystemManagerImpl.java
void executeA(){
SystemA.exectueA();
}
void executeB(){
SystemB.exectueB();
}
But I would like to replace it with some generic solution like
SystemManager.java
#SystemA
void executeA();
#SystemB
void executeB();
SystemManagerImpl.java
void genericMethod(){
// based on the annotation of the method received I am calling correct System class and invoking correct method
}
I dont think this is possible but still I am open to suggestions.

Java Inheritance and Wrapping

I have a generated object that I want to:
Preserve existing functionality of without injecting into the constructor and rewriting every method to call injectedObject.sameMethod().
Add additional functionality to that generated object without modifying the generated object.
add additional functionality to.
For example:
public class GeneratedObject {
public String getThis() { ... }
public String getThat() { ... }
}
public interface ObjectWrapper {
String doThisWithThat();
}
public class ObjectWrapperImpl extends GeneratedObject implements ObjectWrapper {
String doThisWithThat() { ... }
}
However, downcasting is not allowed, what is the proper implementation without rewriting a bunch of redundant code just to wrap the object?
I think decorator pattern may help you: "The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time, independently of other instances of the same class"
Have you tried aspectj? http://www.eclipse.org/aspectj/doc/next/progguide/semantics-declare.html It's a bit complicated but so is your request.
If you can extract an interface from GeneratedObject, then it would be possible to do this using a dynamic proxy. You would make a proxy which implemented the extracted interface and ObjectWrapper, with an invocation handler which passed all calls to methods in the GeneratedObject interface through to the delegate, and sent the doThisWithThat() calls elsewhere.
Proxies aren't pretty, but the ugliness is at least well-localised.

Categories

Resources