I'm not been able to understand by the bold statements:
The key thing to understand here is that the client code inside the
main(..) of the Main class has a reference to the proxy. This means
that method calls on that object reference will be calls on the proxy,
and as such the proxy will be able to delegate to all of the
interceptors (advice) that are relevant to that particular method
call. However, once the call has finally reached the target object,
the SimplePojo reference in this case, any method calls that it may
make on itself, such as this.bar() or this.foo(), are going to be
invoked against the this reference, and not the proxy. This has
important implications. It means that self-invocation is not going to
result in the advice associated with a method invocation getting a
chance to execute.
Code below:
public class Main {
public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.addInterface(Pojo.class);
factory.addAdvice(new RetryAdvice());
Pojo pojo = (Pojo) factory.getProxy();
// this is a method call on the proxy!
pojo.foo();
}
}
public class SimplePojo implements Pojo {
public void foo() {
// this next method invocation is a direct call on the 'this' reference
this.bar();
}
public void bar() {
// some logic...
}
}
Related
I have several methods in a class that require a boolean to be set to true in order to execute correctly.
I could write the if statement in each method, but it is not convenient if I or someone else wants to ad another method. I or he could forget about the check.
Is there a way in java to execute a method before each other methods (exactly like JUnit does with #BeforeEach ) in a class ?
Edit: Lots of very interesting techniques/answers/concepts proposed. I'll be in touch when I've understood them. Thanks.
Lets make a method turnBooleanTrue() where effectively the boolean is set to true in order for the method to be execute correctly.
Then, you can write up your very own InvocationHandler that would intercept calls to your objects, and then reflectively (using reflection API) invoke first the turnBooleanTrue() method followed by the method to which the call was made.
Will look something like this
public class MyClassInvocationHandler implements InvocationHandler {
// initiate an instance of the class
MyClass myClass = new MyClassImpl();
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// look up turnBooleanTrue() method
Method turnBooleanTrue = myClass.getClass().getMethod("turnBooleanTrue");
// invoke the method
turnBooleanTrue.invoke(...); // toggle the boolean
// invoke the method to which the call was made
// pass in instance of class
Object returnObj = method.invoke(myClass, args);
return returnObj;
}
EDIT
Added some lines to have an object of MyClass initialized. You need something to invoke the method on and maintain the state. Changed util to myClass in the code example above.
Considering my use case, it was a bit overkill to use AOP or other concepts. So I basically did a check in each functions.
With AOP, this is how what you need would look:
// wraps around all methods in your class that have a boolean parameter
#Around(value = "#target(*..YourClass) && args(yourBool)", argNames = "jp,yourBool")
Object scheduleRequest(ProceedingJoinPoint jp, boolean yourBool) {
if (yourBool) {
jp.proceed(yourBool);
} else {
throw new RuntimeException("cannot execute this method!");
}
}
This would handle the case that the method take the boolean you say needs evaluation as its (only) parameter. If it comes from a different source, you may need to wire it into the aspect somehow, that depends on your overall design.
I suggest a simple solution by dividing your workflow in four components.
You have an interface you use to execute commands.
You have an interface that defines which commands you can use.
You have one wrapper that analyzes your boolean value.
You have an implementation of the work performing class, that implements the second interface.
Your wrapper initialize the worker.
Your wrapper exposes an action performing command that accepts the executing interface.
if the boolean is true, pass the worker to the executing interface work method.
the executing interfaces work method calls the work function on the command instance interface, the worker.
See it online: https://ideone.com/H6lQO8
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
WorkDistributer wd = new WorkDistributer();
wd.enable();
wd.performAction((w) -> {w.printHello();});
wd.disable();
wd.performAction((w) -> {w.printHello();});
wd.enable();
wd.performAction((w) -> {w.printAnswer();});
wd.disable();
wd.performAction((w) -> {w.printAnswer();});
}
}
class WorkDistributer
{
private boolean enabled = false;
private ActionPerformer worker;
public WorkDistributer() {
this.worker = new Worker();
}
public void enable() {
enabled = true;
}
public void disable() {
enabled = false;
}
public void performAction(ActionCommand command) {
if(this.enabled) {
command.run(this.worker);
}
}
}
class Worker implements ActionPerformer {
public void printHello() {
System.out.println("hello");
}
public void printAnswer() {
System.out.println(21 * 2);
}
}
interface ActionPerformer {
public void printHello();
public void printAnswer();
}
interface ActionCommand {
public void run(ActionPerformer worker);
}
Suppose that I have the following method:
void test () {...}
I am getting this method via reflection, but invoking it will be very slow, so I want to get Runnable from it as if I will write
this::test
Is there any way to achieve this?
I need an implementation for method like this: Runnable toRunnable(Method method); So we are getting a Method and we need to return Runnable
This is not exactly equivalent to this::test, since that also uses the this instance to bind to, so you will also have to pass an instance to bind to. But then you can use method handles, which is the underlying implementation for something like this::test.
With a class like this:
public class MyClass {
public void test() {
System.out.println("Test Called");
}
}
You can create this method:
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
public static Runnable toRunnable(Method method, Object instance) throws ReflectiveOperationException {
Lookup lookup = lookup();
MethodHandle test = lookup.unreflect(method);
try {
return (Runnable) LambdaMetafactory.metafactory(
lookup,
"run",
methodType(Runnable.class, instance.getClass()),
methodType(void.class),
test,
methodType(void.class)
).getTarget().invoke(instance);
} catch (Throwable e) {
throw new RuntimeException("Should not occur", e);
}
}
And call it like this:
Object ref = new MyClass(); // get from somewhere
Runnable result = toRunnable(ref.getClass().getMethod("test"), ref);
result.run(); // prints 'Test Called'
The caveat is that the test method has to be accessible from the point at which you're calling lookup(), you can get around this either by passing the Lookup to the method manually, and creating it at a place where you can access the test method. Or if you're in Java 9 you can use privateLookup(Class<?>, Lookup) instead, but the Lookup you pass to that needs to be created in the same module as the method you're trying to access. (in short, method handles has a few more access restrictions to it). But if the method and class you're trying to access are publicly accessible then there's no problem.
Which are differences between andAnswer() and andDelegateTo() methods in EasyMock in terms of usage?
First difference
I know that when andAnswer method is used, it is skipped the constructor call. This is important if the constructor makes extra things.
class Dummy {
public Dummy(Object someArgument) {
// some validations of arguments
System.out.println("the constructor is called");
}
public Object method() {
System.out.println("the method is called");
return new Object();
}
}
#Test
public void testSt1() {
Dummy mock = EasyMock.createMock(Dummy.class);
EasyMock.expect(mock.method()).andAnswer(new IAnswer<Object>() {
#Override
public Object answer() throws Throwable {
System.out.println("mocked method is called");
return new Object();
}
} );
EasyMock.replay(mock);
mock.method();
}
#Test
public void testSt2() {
Dummy mock = EasyMock.createMock(Dummy.class);
EasyMock.expect(mock.method()).andDelegateTo(new Dummy(new Dummy(new Object()) {
#Override
public Object method() {
System.out.println("mocked method is called");
return new Object();
}
} );
EasyMock.replay(mock);
mock.method();
}
Results:
testSt1() does not call the constructor of Dummy
testSt2() calls the constructor of Dummy
What are the other differences?
The purpose of the two methods is to provide different levels of responsibility for your tests. Your example isn't that great, though.
Here's a simple method that demonstrates how functionally these two provide different test expectations.
public String foo() throws Exception {
throw new Exception();
}
With andAnswer, you can make a mocked version of this method return a String, even though it would never return one in practice. Your use of andAnswer implies an expected response.
With andDelegateTo, this will always throw an Exception. Your use of andDelegateTo implies an actual response.
andAnswer means your test-specific code will handle the response. For example, if you create a ParrotAnswer for a MockDao update method, the Parrot will return the updated Object, but no Dao is actually instantiated in the process. This is nice for unit testing where you basically walk the test subject through, but doesn't help if your mocked method doesn't do as what you method actually does.
andDelegateTo allows you to provide an actual Object implementing the interface to handle the response. We're allowing our test subject controlled access to a resource, rather than providing unrestricted access to a full resource. benefit of this is that you can test integration into a test environment, but minimize actual changes to the test environment. For example, you can delegate get to a wired Dao to fetch an actual live value from the Db, and mock the delete method, so you don't actually delete that same value during testing (and having to recreate it again later to do the same test if it has a static id, for example).
I came across a code which my colleague uses inside an eventListner, which is :
private void someActionPerformed(java.awt.event.ActionEvent evt) {
new className().methodName(); //public class and public void methodName()
}
I was pretty sure that :
private void someActionPerformed(java.awt.event.ActionEvent evt) {
className ref = new className(); //public class and public void
ref.methodName();
}
is the better option than his, as the previous method instantiates a class every time it is called.
Am I wrong? Any suggestion is appreciated, Please correct me if I am wrong
.
Both do the same thing, however one of them (the first) is 1 line shorter.
Your approach is usually recommended when you need to go through more than 2-3 objects, so new Foo().getBar1().getBar2().doStuff() is usually not recommended since it can degrade into spaghetti code and hinder the understandability of the code.
The first code-sample instantiates a new Object of Type className.methodName.
For this to work, methodName has to be a static nested class of Type className.
Attention: This could as well be a typo. Did you mean new className().methodName()?
The second sample creates a new instance of className and calls its method methodName.
Some example code:
public class Test {
public static void main(String[] args) {
new Test.test(); // instantiates the inner class
Test t = new Test(); // instantiates Test
t.test(); // calls method #test of Test-instance
}
public String test() {
return "Test";
}
public static class test {
}
}
In order to judge what's the best solution your example does not give enought information. Is the method some static utility code or is an instance of className useful? It depends...
Whenever an object is instantiated but is not assigned a reference variable, it is called anonymous object instantiation.
With anonymous object you can call it's instance method also:
new className().methodName();
In your case this is the anonymous object which doesn't have reference variable.
In the statements:
className ref = new className();
ref.methodName();
ref is the reference variable to hold the className object, so you can call instance methods of className on ref variable.
The benefit of using anonymous notation is, if you want to do only limited (may be calling single method and so on..) operation with the underlying object the it is a good approach. But if you needs to perform more operation with the underlying object then you need to keep that object in a reference variable so that you can use that reference to perform multiple operations with that object.
Regarding the performance there are not much difference as both are in methods scope, as soon as method completes both the objects are valid candidates for the garbage collection.
Both the methods instantiates a class in the code. If you want to reuse the class object every time the method is called, you can declare it as a member of the class where the method resides. For eg:
class AnotherClass{
private ClassName ref;
AnotherClass(){
ref = new ClassName()
}
private void someActionPerformed(java.awt.event.ActionEvent evt) {
ref.methodName();
}
}
This way, everytime your method someActionPerformed is called on an object of AnotherClass, it will reuse the ref object instead of instantiating it everytime.
About the edit,
public class ClassName {
static class InnerClass{
// A static inner class
}
public void methodName() {
// A method
}
}
class AnotherClass{
private void someActionPerformed(java.awt.event.ActionEvent evt){
// This creates an instance of the inner class `InnerClass`
new ClassName.InnerClass();
// However I believe, you wanted to do:
new ClassName().methodName();
}
}
new className.methodName(); --> if you are using this convention in your code then calling another method name will result to different object's method name and you lose your values.
className ref = new className();
ref.methodName(); -> here you are creating a reference and make assiging a newly created object and you are calling the method's on it. Suppose if you want to call another method on the same object it will helps.
The first approach they will mostly use for listenere which is anonymous class.
Both options create a new Class every time they are called. The advantage of the second over the first option would be if you wanted to reuse that class later in the method.
IMHO this is a little bit more understandable code for the answer provided by DaniEll
public class Test {
public static void main(String[] args) {
new Test.test(); // instantiates the inner class
Test t = new Test(); // instantiates Test
t.test(); // calls method #test of Test-instance
}
public void test() {
System.out.println("Outer class");
}
public static class test {
public test() {
System.out.println("Inner class");
}
}
}
I have a static method, that is used in multiple places, mostly in static initialization block. It takes a Class object as parameter, and returns the class's instance.
I want to mock this static method only when particular Class object is used as parameter. But when the method is called from other places, with different Class objects, it returns null.
How can we have the static method execute actual implementation in case of parameters other than the mocked one?
class ABC{
void someMethod(){
Node impl = ServiceFactory.getImpl(Node.class); //need to mock this call
impl.xyz();
}
}
class SomeOtherClass{
static Line impl = ServiceFactory.getImpl(Line.class); //the mock code below returns null here
}
class TestABC{
#Mocked ServiceFactory fact;
#Test
public void testSomeMethod(){
new NonStrictExpectations(){
ServiceFactory.getImpl(Node.class);
returns(new NodeImpl());
}
}
}
What you want is a form of "partial mocking", specifically dynamic partial mocking in the JMockit API:
#Test
public void testSomeMethod() {
new NonStrictExpectations(ServiceFactory.class) {{
ServiceFactory.getImpl(Node.class); result = new NodeImpl();
}};
// Call tested code...
}
Only the invocations that match a recorded expectation will get mocked. Others will execute the real implementation, when the dynamically mocked class is called.