Convenient way to create a wrapper - java

Problem
I need to perform logic over and over on the results of several methods. The methods can have arbitrary result types. The simple use case looks like this:
A wrapper class with an execute method:
/**
* Wrapper class which executes inner logic, processes the result of that logic and returns the processed result.
*
* #param <T>
*/
public abstract class Wrapper<T> {
/**
* Perform inner logic
*/
public abstract T run();
/**
* Invoke inner logic and process it.
*/
public T execute() {
T result = run();
// TODO: process result
return result;
}
}
And the logic in an inner class, example usage of the Wrapper:
public class WrapperDemo {
/**
* Simple invocation of the inner logic and then the outer logic
*/
public static Boolean testMethod() {
// wrap around logic and execute
return new Wrapper<Boolean>() {
#Override
public Boolean run() {
// TODO: perform logic, simply returning true for now
return Boolean.TRUE;
}
}.execute();
}
public static void main(String[] args) {
// demo method invocation
Boolean result = WrapperDemo.testMethod();
// process result
System.out.println(result);
System.exit(0);
}
}
I'll have to apply this to several 100s of methods.
Question
Does anyone know a more convenient way to code this with less code for testMethod (e. g. maybe annotation)?

If you have Java 8, you could write the following:
public static <T> T execute(Wrapper<T> wrapper) {
return wrapper.execute();
}
And then use it as following:
public static Boolean testMethod() {
return execute(()-> {
return Boolean.TRUE;
});
}
Though I fail to see how this is better than the following:
public static <T> T wrap(T result) {
// Process result
return result
}
And using it like this:
public static Boolean testMethod() {
return wrap(Boolean.TRUE);
}

If you want to use annotations, you should use a tool that allows such reflection to be used. Basic reflection can't be used because then you can't "intercept" the call. Java's Proxy might help, but you're constrained to use interfaces, which is not always what people want.
cglib is a library that removes all that hassle. With that, you can try the following:
#Target(METHOD)
#Retention(RUNTIME)
public #interface Wrap {
}
class Demo {
#Wrap
public Boolean testMethod() {
return Boolean.TRUE;
}
}
class Wrapper {
public <T> T newInstance(Class<T> type) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(type);
enhancer.setCallback(new InvocationHandler(){
#Override public Object invoke(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
Object result = proxy.invokeSuper(obj, args);
if (method.isAnnotationPresent(Wrap.class)) {
execute(result);
}
return result;
}
});
return enhancer.create();
}
public void execute(Object result) {
// Add custom behavior to #Wrap-ped methods.
}
}
Then you have to call the wrapper like this:
Demo demo = new Wrapper().newInstance(Demo.class);
demo.testMethod();
Other libraries exist too, like Byte Buddy or Javassist. But be careful because Java 9 is very close and forced those libraries into changing their core business very, very quick, possibly making them unstable.

In Java 8, by combination of lambda and default method, you can achieve similar thing without much change in your API (except you need to make Wrapper an interface instead of abstract class)
public interface Wrapper<T> {
public T run();
default public T execute() {
T result = run();
// TODO: process result
return result;
}
}
Then you can call it by
public static Boolean testMethod() {
Wrapper<Boolean> w = ()-> {return Boolean.TRUE;};
return w.execute();
}
But personally I don't think it make much sense.
If you want to add extra logic around a logic, probably what you need is a little twist:
public class ExtraAction<T> {
Supplier<T> supplier;
public ExtraAction(Supplier<T> supplier) {
this.supplier = supplier;
}
public T execute() {
T result = this.supplier.get();
// some extra processsing
return result;
}
}
so it will be called like
Boolean result = new ExtraAction<>(()->{return Boolean.TRUE}).execute();
Even better, make your logic in Wrapper a Function<X,Y>, and make up something to chain your Supplier and Function together, so it will look like
result = Foo.forInput( ()-> { return logicToGetResult(); })
.doExtra(ExtraAction::whateverAction).result();

Related

Multiple type parameter in java

I need a function that accepts both types of arguments and has the same body.
How can I do it?
For example:
// I have:
public someFunction(Pageable input) { the same body }
public someFunction(Sort input) { the same body }
// I need
public someFunction(PageableOrSort input) {the same body}
You can try this way, but this is bad practice:
public void someFunction (Object input){
if (input instanceof Pageable) {
Pageable pageable = (Pageable) input;
/* do something else */ }
if (input instanceof Sort) {
Sort sort = (Sort) input;
/* do something else */
}
You could just create a wrapper object that has a Pageable property and a Sort property:
public Class MyWrapper {
public Sort mySort;
public Pageable myPageable;
}
Then you can set both properties then have your method have a MyWrapper as a parameter.
But what is the reason for wanting a single method? Having an overloaded method is good practice in a situation like this and you can abstract your method body to where there is no much duplicate code depending on the logic.
Assume your function someFunction does something like this
input.doA();
input.doB();
Then create an interface that contains those two methods
interface PageableOrSort {
void doA();
void doB();
}
and define your method as
void someFunction(PageableOrSort input) {
input.doA();
input.doB();
}
And make your classes implement the interface
public class Pageable implements PageableOrSort {
#Override
public void doA() {
//do stuff
}
#Override
public void doB() {
//do stuff
}
}
and the same for the other class. Then you can call the method with any class implementing the interface
Pageable pageable = new Pageable();
//...
this.someFunction(pageable)

Java - "intercept" a private method

I know this has been asked before, and the answer is usually "you can't" and/or "don't," but I'm trying this anyway.
The context is that I'm trying to set up some "black magic" to aid in testing. My code is running ultimately under JUnit and the nature of the system is such that, while I have access to most any library I could want (ByteBuddy, Javassist, etc), I can't play around with the code prior to it running, I'm stuck with working with classes on the fly.
Here's the setup:
// External Library that I have no control over:
package com.external.stuff;
/** This is the thing I ultimately want to capture a specific instance of. */
public class Target {...}
public interface IFace {
void someMethod();
}
class IFaceImpl {
#Override
void someMethod() {
...
Target t = getTarget(...);
doSomethingWithTarget(t);
...
}
private Target getTarget() {...}
private void doSomethingWithTarget(Target t) {...}
}
Within my test magic-ness, I have an instance of IFace, which I happen to know is an IFaceImpl. What I'd like to do is be able to steal the instance of Target produced internally. Effectively, this would have the same effect as the following (if private methods were overrideable):
class MyIFaceImpl extends IFaceImpl{
private Consumer<Target> targetStealer;
#Override
void someMethod() {
...
Target t = getTarget(...);
doSomethingWithTarget(t);
...
}
/** "Override" either this method or the next one. */
private Target getTarget() {
Target t = super.getTarget();
targetStealer.accept(t);
return t;
}
private void doSomethingWithTarget(Target t) {
targetStealer.accept(t);
super.doSomethingWithTarget(t);
}
}
But, of course, that doesn't work as private methods cannot be overridden.
So the next type of approach would be something like ByteBuddy or Javassist
public static class Interceptor {
private final Consumer<Target> targetStealer;
// ctor elided
public void doSomethingWithTarget(Target t) {
targetStealer.accept(t);
}
}
/** Using ByteBuddy. */
IFace byteBuddyBlackMagic(
IFace iface /* known IFaceImpl*/,
Consumer<Target> targetStealer) {
return (IFace) new ByteBuddy()
.subClass(iface.getClass())
.method(ElementMatchers.named("doSomethingWithTarget"))
.intercept(MethodDelegation.to(new Interceptor(t))
.make()
.load(...)
.getLoaded()
.newInstance()
}
/** Or, using Javassist */
IFace javassistBlackMagic(
IFace iface /* known IFaceImpl*/,
Consumer<Target> targetStealer) {
ProxyFactory factory = new ProxyFactory();
factory.setSuperClass(iface.getClass());
Class subClass = factory.createClass();
IFace = (IFace) subClass.newInstance();
MethodHandler handler =
new MethodHandler() {
#Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
if (thisMethod.getName().equals("doSomethingWithTarget")) {
consumer.accept((Target) args[0]);
}
return proceed.invoke(self, args);
}
};
((ProxyObject) instance).setHandler(handler);
return instance;
}
and as I was testing out these pattern, it worked in other cases where the method I wanted to intercept was package-local, but not for private methods (expected for ByteBuddy, per the documentation).
So, yes, I recognize that this is attempting to invoke dark powers, and that this is normally frowned upon. The question remains, is this doable?
using javassist you can instrument the someMethod( ) in the IClassImpl class to send the instance of the TargetClass to someother class and store it there or do other manipulations using the instance created.
this can be achieved using the insertAfter( ) method in javassist .
For example :
method.insertAfter( "TestClass.storeTargetInst(t)" ); // t is the instance of Target class in IClassImpl.someMethod
TestClass{
public static void storeTargetInst(Object o){ ### code to store instance ###}
}
The insertAfter() method injects a line of code before the return statement of a method or as the last line of a method in case of void methods.
Refer this link for more information on the methods available for instrumentation.
Hope this helps!
If you can execute some code in like public static void main block, or just before IFaceImpl is loaded, then you can use javassist to edit that class directly before it is loaded - so you can change method to be public, add another one, etc:
public class Main {
public static void main(String[] args) throws Exception {
// this would return "original"
// System.out.println(IFace.getIFace().getName());
// IFaceImpl class is not yet loaded by jvm
CtClass ctClass = ClassPool.getDefault().get("lib.IFaceImpl");
CtMethod getTargetMethod = ctClass.getDeclaredMethod("getTarget");
getTargetMethod.setBody("{ return app.Main.myTarget(); }");
ctClass.toClass(); // now we load our modified class
// yay!
System.out.println(IFace.getIFace().getName());
}
public static Target myTarget() {
return new Target("modified");
}
}
where library code is like this:
public interface IFace {
String getName();
static IFace getIFace() {
return new IFaceImpl();
}
}
class IFaceImpl implements IFace {
#Override public String getName() {
return getTarget().getName();
}
private Target getTarget() {
return new Target("original");
}
}
public class Target {
private final String name;
public Target(String name) {this.name = name;}
public String getName() { return this.name; }
}
If there is no way to execute your code before that class is loaded, then you need to use instrumentalization, I will use byte-buddy-agent library to make this simpler:
public class Main {
public static void main(String[] args) throws Exception {
// prints "original"
System.out.println(IFace.getIFace().getName());
Instrumentation instrumentation = ByteBuddyAgent.install();
Class<?> implClass = IFace.getIFace().getClass();
CtClass ctClass = ClassPool.getDefault().get(implClass.getName());
CtMethod getTargetMethod = ctClass.getDeclaredMethod("getTarget");
getTargetMethod.setBody("{ return app.Main.myTarget(); }");
instrumentation.redefineClasses(new ClassDefinition(implClass, ctClass.toBytecode()));
// yay!
System.out.println(IFace.getIFace().getName());
}
public static Target myTarget() {
return new Target("modified");
}
}
Both versions might be much more problematic to run on java 9 and above due to how modules work, you might need to add additional startup flags.
Note that on java 8 instrumentalization might not be present on client JRE. (but with few more hacks can be added, even at runtime)

Invoking a method of an anonymous class without reflection in java

I want to do something like this
static <T> T mine()
{
return new Object(){void hello(){}};
}
so that I can do this
mine().hello();
the intend is to do something like this
mine.hello().hi().bye();
so either I declare classes each with 1 method hello,hi,bye and than return there instances or somehow I could return an anonymous class(with newly defined method) form each method like above. so that I dont have to write lot of classes.
Like it I can do
static <T> T tunnel(T t)
{
return t;
}
tunnel(new Object()
{
void hello()
{
System.out.println("hello");
}
}).hello();
but its of no use, I want to return anonymous object(created in tunnel itself) from tunnel , instead of returning passed argument
You probably want a fluent class. Something like
public class MyFluentClass {
public MyFluentClass methodOne() {
// do something
return this;
}
public MyFluentClass methodTwo() {
// do something
return this;
}
}
And then in your main method:
MyFluentClass myFuent = new MyFluentClass();
myFluent.methodOne().methodTwo();

Unit test with wrapped public static method Java

I am not very familiar with Unit Tests, I know that they are very important for code quality, and I want to write some in my project. I recently run into some issues. The context is that, I am writing the testClassA for my Aclass, but some functions in Aclass depend on BClass.
BClass is a utility function, so it has many public static function.
AClass uses Bclass's functions :
public class Aclass{
public boolean Afunction()
{
String result = Bclass.Bfunction();
//do stuff with result
return true
}
}
public class Bclass{
public static String Bfunction()
{
//function code
}
}
I want that everytime the BClass.Bfunction is called, then I can return what I want without really execute the real Bfunction in Bclass, so my Aclass doesn't depend on other class in my test. Is it possible ?
One approach that limits your changes to just the Aclass, and eliminates the dependency on Bclass (as you asked for) is extract-and-override:
Identify the code you wish to bypass in your test and extract it to a method.
Override that method in a sub-class of your class-under test. In this overidden method, you can code whatever mock behavior is appropriate for the test:
So your modified Aclass would look like this:
public class Aclass {
public boolean Afunction() {
String result = doBfunction();
// do stuff with result
return true;
}
// This is your "extracted" method.
protected doBfunction() {
return Bclass.Bfunction();
}
}
and your test class would look like this:
class AClassTest {
#Test
public void testAFunction() {
Aclass testObject = new TestableAclass();
boolean value = testObject.AFunction();
// now you can assert on the return value
}
class TestableAclass extends Aclass {
#Override
protected String doBfunction() {
// Here you can do whatever you want to simulate this method
return "some string";
}
}
}

Is it convenient to use java.lang.Void for classes that doesn't return anything?

I'm developing a clustering framework and I have the following interface
in order to provide a way to execute a piece of code on another node in the cluster:
interface Operation<V> {
V run();
int getService();
}
However, the user may not care about the result of an operation.
In this case I need to provide a convenient way for them. I have two options:
I can tell them to use java.lang.Void as parameter and check the return type in remote server and return the result if the generic type is not Void:
new Operation<Void> {
public Void run() {
//
return null;
}
public int getService() { return 1; }
}
However, even if they use java.lang.Void,
they still need to return something in run method so
it might not be a good way to do something like that.
Also I can create another interface that doesn't not return anything.
However, now we have two types and I'm afraid it can be much for complex than the first way.
interface FireAndForgetOperation {
void run();
int getService();
}
Which way do you think is more convenient?
I think your first approach is convenient. It is used inside some java libraries. One example is the Callback interface in JavaFX (https://docs.oracle.com/javafx/2/api/javafx/util/Callback.html).
Code that needs to use a callback and does want any returned value declares the callback as:
CallBack<SomeClass, Void> myCallBack;
And in the call method you return null;
I would definitely do something like this to avoid exposing something that doesn't have to be:
public interface Operation<V> {
V run();
public int getService();
}
abstract public class VoidOperation implements Operation<Void> {
public final Void run() {
runVoid();
return null;
}
abstract public void runVoid();
abstract public int getService();
}
Usage :
new Operation<String>() {
public String run() {
return null;
}
public int getService() { return 1; }
};
new VoidOperation() {
public void runVoid() {
}
public int getService() { return 1; }
};

Categories