I'm using Guice to make an interceptor for all methods in one class except the ones annotated with a specific class I created:
Here's the AbstractModule:
public class MyModule extends AbstractModule {
#Override
protected void configure() {
bindInterceptor(
Matchers.subclassesOf(MyFacade.class),
Matchers.not(Matchers.annotatedWith(DAO.class)),
new MyInterceptor());
}
}
Now, is it possible to make my MethodInterceptor ignore all methods in MyFacade when they are called by another method in the same class (MyFacade)?
For example:
public class MyFacade{
#DAO
public void doSomething(){
...
}
public void a(){
...
b();
}
public void b(){
...
}
}
I don't want that the interceptor intercepts the call from method a() to method b().
Thanks!
There's no easy way for the intercepted to know which class is calling it. Also, under most circumstances, you would expect a call to b() to run the intercepted method—such as ensuring a DB transaction is opened and closed appropriately. If you need to ensure that interception only occurs on external calls, you'll have to be a little clever.
Option 1: Rewrite the interceptor to keep state
Consider rewriting your MethodInterceptor to have a guard checking whether it's in the middle of an intercepted method. Remember, bindInterceptor accepts instances, so if it comes to it you can keep call stack state in there. This is unusual—interceptors are typically assumed to be stateless—so document it well.
/**
* Prevents internal interceptor calls from within intercepted methods.
* Not thread safe.
*/
public abstract class GuardedInteceptor implements MethodInterceptor {
private boolean executionInProgress = false;
/** No-op if in the middle of an intercepted method. */
public Object invoke(MethodInvocation invocation) throws Throwable {
if (executionInProgress) {
return invocation.proceed();
}
executionInProgress = true;
Object returnValue = null;
try {
runBefore();
returnValue = invocation.proceed();
runAfter();
} finally {
executionInProgress = false;
}
return returnValue;
}
protected abstract void runBefore();
protected abstract void runAfter();
}
Option 2: Rewrite the intercepted class to delegate to a private method
In your situation I would have b() delegate to private method bInternal() and call that instead of b() from within MyFacade. Guice AOP can't intercept private methods, so you don't need to worry about annotating or configuring anything else. This also allows the individual systems to choose whether to call the possibly-overridden-or-intercepted public methods or the effectively-final, predictable private methods. AOP interception is implemented through inheritance, so the standard rules about designing and documenting for inheritance apply here.
Related
I have an interface with 1 method signature:
public interface UrlProvider {
String getUrl();
}
There are 2 implementations of this interface, and one of them has a public method whose signature is not in the interface because it only makes sense to be inside the implementation:
public class UrlProviderImpl implements UrlProvider {
#Override
public String getUrl() {
//implementation
}
public String getUrlAndAppend() {
//implementation
}
}
There's a third class that's going to have a UrlProvider field and Spring is going to handle the dependency injection and instantiating the correct beans. Is it possible to call getUrlAndAppend() on the interface level without explicitly instantiating the implementation?
This is what I am trying to achieve:
public class ThirdClass {
private final UrlProvider urlProvider;
public void myMethod() {
urlProvider.getUrlAndAppend();
}
}
In terms of design, how this is usually handled?
If you know when you want the extra functionality in some places, consider making a new interface, or injecting the specific implementation in the places you know you need the extra functionality. Without reflection (which is a terrible idea; don't do it), you can't access that method from the interface.
public interface AppendingUrlProvider extends UrlProvider {
String getUrlAndAppend();
}
public class AppendingUrlProviderImpl implements AppendingUrlProvider {
#Override
public String getUrl() {
// implementation
}
#Override
public String getUrlAndAppend() {
// implementation
}
}
////
// Or modify your existing ThirdClass
////
public class ThirdClass {
// inject the implementation, not the interface
private final UrlProviderImpl urlProvider;
public void myMethod() {
urlProvider.getUrlAndAppend();
}
}
Solutions aside, the first thing you should really do is figure out exactly why you need this extra public method on just one of the implementations. Is this something that callers should be doing instead of the implementation? Should this be on the interface? Is this only needed for testing? Only you can answer this, but it's worth taking a step back to make sure you've set up your codebase for success and longterm maintainability.
Did you try your own code?
You can't call a method that belongs to an instance of a class, if you do not instantiate that class.
In your example, if you call myMethod without instantiating UrlProvider you will get a NullPtrException.
If you want to have access to getUrlAndAppend from the interface, you will need to declare that method as "default" in the interface itself or as Static from the implementation (and that way you do not need to instantiate it to call the method), but I'm having trouble to understand what you want to achieve from this.
I'm curious how this all works. I have an interface, let's call it A. When I look at A, it has most of the methods I need, but not all, and I don't have control over interface A, so I extend it with interface B which implements the 1 or whatever number of methods that I need on top of A.
public interface B extends A {
String doSomethingFun(String blah);
}
A has an implementation class called Client. In just a second I'm going to create my own implementation class of B called MyDefaultClient.
I then create a concrete class that implements B, like this:
#Component
public class MyDefaultClient implements B {
private A myClient;
#Autowired
public MyDefaultClient(A myClient) {
this.myClient = myClient;
}
#Override
public String doSomethingFun(String filename) {
// custom business logic
}
#Override
public String serviceName() {
return myClient.serviceName();
}
#Override
public void close() {
myClient.close();
}
}
serviceName() and close() are methods that A forces its implementors to implement. There are other methods though that have default implementations that aren't forcing me to implement them, I assume simply because they have default implementations.
At this point I have a concrete class that I can instantiate in other places and call all of both A and B's methods on it. But is that only because in the interface there are default implementations for these methods, like this?
default Blah someMethodInA(String thing) {
throw new UnsupportedOperationException();
}
If I use this code and call myDefaultClient.doSomethingFun("hello") I'm pretty certain that will do the thing I want it to do. But what about if I call myDefaultClient.someMethodInA()? Will it call the implemented method in Client, which is A's implementor? Or will it fall on the floor and complain with an UnsupportedOperationException? If the latter, is there any way I can structure this so that I can call all of A's methods from B's implementor?
If you want MyDefaultClient to inherit implementations from Client, then it has to extend Client, like this:
class MyDefaultClient extends Client implements B
{
...
}
Then, if Client implements A, you will only have to provide implementations for the new methods that B adds.
or... you can continue your current pattern and explicitly delegate all the calls you want to a field of type A, but you will have to do them all explicitly, even the methods with default implementations. The default implementations will continue the throw exceptions if you don't override them.
An interface can have any number of default methods. Check this for more details. Given below is an example to demonstrate how default methods and extending an interface work:
public interface InterfaceA {
public void toBeImplementedA();
default void hello() {
System.out.println("Hello");
}
default void hi() {
System.out.println("Hi");
}
}
public interface InterfaceB extends InterfaceA {
public void toBeImplementedB();
}
public class AnImplClass implements InterfaceB {
#Override
public void toBeImplementedA() {
System.out.println("toBeImplementedA");
}
#Override
public void toBeImplementedB() {
System.out.println("toBeImplementedB");
}
}
public class Main {
public static void main(String[] args) {
InterfaceB obj = new AnImplClass();
obj.toBeImplementedA();
obj.toBeImplementedB();
obj.hello();
obj.hi();
}
}
Output:
toBeImplementedA
toBeImplementedB
Hello
Hi
Feel free to comment in case of any doubt.
Interfaces can contain default methods. These were added to Java so that an interface could be updated without forcing implementing code to be rewritten.¹
Default methods provide an implementation if your implementing class does not implement them.
When you call methods on an object, the overridden method is always called.
Any other implementations in the super classes / interfaces are used when there is a lack of implementation.
Even if you refer to MyDefaultClient as A,
A myImplementation = new MyDefaultClient();
Under the hood myImplementation is still an instance of MyDefaultClient even though the code views it as A. Therefore your overriden method will be used when doSomethingFun is called.
#Override
public String doSomethingFun(String filename) {
// custom business logic
}
¹ Source: https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
Given this class:
abstract class Foo{
public Foo(){...}
public abstract void checkable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
Is there any code I can put in Foo's constructor to make calledWhenCheckableIsCalled get called when checkable is called?
Note: This is a gross simplification of an actual project I am working on.
Edit: I have already implemented a template pattern workaround. I just wondered if there was another way to do this I am missing. (Perhaps using reflection.)
Looks like a template method pattern.
But then you must implement Foo.checkable() and introduce another abstract method to delegate to.
abstract class Foo{
public Foo(){}
public void checkable(){
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
I would also suggest to make checkable() final in this case so that you can be sure that checkable() can not implemented in another way as you expected.
In addition to Brian Roach's comment
The downside is that the protected can be expanded to public in the subclass, so you can't explicitly enforce it.
That's true, but you can prevent a Foo instance from being instantiated if a subclass increases the visibility of doCheckable. Therefore you have to introduce a verification whenever an object is instantiated. I would recommend to use an initializer code so that the verification is executed on every constructor that exists. Then it can not be forgotten to invoke and therefore be by-passed.
For example:
abstract class Foo {
{ // instance initializer code ensures that enforceDoCheckableVisibility
// is invoked for every constructor
enforceDoCheckableVisibility();
}
public Foo() {...}
public Foo(Object o) {...}
private void enforceDoCheckableVisibility() {
Class<?> currentClass = getClass();
while (currentClass != Foo.class) {
try {
Method doCheckableMethod = currentClass.getDeclaredMethod("doCheckable");
if (Modifier.isPublic(doCheckableMethod.getModifiers())) {
throw new RuntimeException("Visibility of "
+ currentClass.getSimpleName()
+ ".doCheckable() must not be public");
}
} catch (SecurityException | NoSuchMethodException e) {}
currentClass = currentClass.getSuperclass();
}
}
}
Since the check is implemented using reflection the downside is that it is only checked at runtime. So you will not have compiler support of course. But this approach let you enforce that an instance of a Foo can only exist if it fulfills your contract.
No, the constructor will get invoked once during the object initialisation. You can however get your subclass that provides the implementation to call the method in the super class:
class Bar extends Foo {
// implementation of abstract method
public void checkable(){
super.calledWhenCheckableIsCalled(); // call to parent's method
...
}
}
EDIT
You could achieve this with aspects. Using an aspect you can intercept each call to a method by referring to the abstract parent method. This leaves you free from interfering eith the child code. Your calledWhenCheckableIsCalled code would then become part of the intercepting code.
abstract class Foo {
// use pointcut to intercept here
public void checkable();
}
There is no way as you are forcing that method to implement in child.
An awkward suggestion will be know from child implementation. I mean there is no clean way AFAIK
abstract class foo {
public abstract void bar();
public void moo() {
System.out.println("some code");
this.bar();
System.out.println("more code");
}
}
now if moo is called, the underlying implementation of bar will be used, it is just a small paradigm shift from what you want.
so your end user would call moo instead of bar, but he still needs to implement bar
Nope, an abstract method doesn't have a body. You could, however, chain your method like this:
abstract class Foo {
void callMeInstead() {
// do common
callMeImplementation();
}
abstract void callMeImplementation();
}
It looks to me like you're looking for the template pattern:
public abstract class Template {
public final void checkable() {
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
private void calledWhenCheckableIsCalled() {
System.out.println("checkable was called");
}
}
Now, each time checkable() is called, calledWhenCheckableIsCalled() is also called. And the suclass must still provide the actual implementation of checkable(), by implementing the doCheckable() method.
Note that making checkable() final prevents a subclass from overriding it and thus bypassing the call to calledWhenCheckableIsCalled().
I have been using delegation pattern to wrap an object created by a factory in a 3rd party library. Recently, the library added a protected method in the base class and my wrapper class doesn't work any longer. Does anyone have a good solution without resorting to reflection?
This is in 3rd party library and in their package,
public class Base {
public void foo();
protected void bar(); // Newly added
}
This is in my own package,
public class MyWrapper extends Base {
private Base delegate;
public MyWrapper(Base delegate) {
this.delegate = delegate;
}
public void foo() {
delegate.foo()
}
protected void bar() {
// Don't know what to do
}
}
EDIT: My original post wasn't clear. These 2 classes are in different packages.
To answer the question why I need delegation. This is a typical use-case of Delegation/Wrapper pattern and I can't show it here in a few lines of code. The library exposes Base class but the actual object from their factory is a derived class of Base. The actual class changes depending on configuration. So I don't know what delegate is. Therefore straight inheritance pattern doesn't work here.
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
protected has package access too, do you see any specific issue with this:
class Base {
public void foo(){};
protected void bar(){}; // Newly added
}
class MyWrapper {
private Base delegate;
public MyWrapper(Base delegate) {
this.delegate = delegate;
}
public void foo() {
delegate.foo();
}
protected void bar() {
// Don't know what to do
delegate.bar(); //since its in same package, it can be referenced, do you expect compile time error?
}
}
Further while using delegator pattern why wrapper class extends Base class, I don't see specific need since you already have an instance of Base. To me it seems more of an decorator.
You don't need (or shouldn't?) delegate that bar method.
If the library defined a protected method. It doesn't want user (of course in different package) to invoke that method, unless creating subclass of that type. You are trying to break the rule.
If you want to do it, there is way, you create a subtype of Base,say SubBase, you create object of SubBase instead of Base, then pass subBase to your wrapper. then you could in your wrapper bar() method write delegate.bar() In this way, the SubBase is actually the delegate, or to say your wrapper is delegating SubBase not Base
I think you know what I mean, so I just don't type example codes, only this line I guess it is enough:
//Wrapper
private SubBase delegate;
You see the wrapper is not necessary any longer if you have SubBase. You could even define a public void pubBar() in your SubBase, and there you call this.bar(). in this way all objects of SubBase have access to the protected method (via pubBar()), no matter from which package
I'm using Spring for injecting in Wrapper the "Base delegate" from another module and for getting the delegate i'm using a pojo factory.
<bean id="interfaceDelegate" factory-bean="DelegatePojoFactory"
factory-method="getMyDelegateInstance">
<constructor-arg index="0">
<value>OnLine</value>
</constructor-arg>
</bean>
<bean id="wrapper" class="path.Wrapper">
<property name="delegate" ref="interfaceDelegate"></property>
</bean>
I get the impression that the Base class is either an interface or an abstract class. If so, you must implement the bar() method, for example by using any of the three methods listed below.
Side note, if Base is a normal class, you do not have do anything (a call to an instance of MyWrapper.bar() will actually result in a call to Base.bar().
Delegate to the parent object
This is usually a good idea if the bar() method is used as a callback in the 3rd party API:
#Override
protected void bar() {
delegate.bar();
}
Do nothing
Just added an empty method to avoid compile errors:
#Override
protected void bar() {
// silently ignored
}
Throw an exception
Violently prevent any usage of the new method:
#Override
protected void bar() {
throw new UnsupportedOperationException("not implemented");
}
As a side note, a more robust construction is to prefer composition over inheritance to decouple your implementation from the 3rd party implementation, e.g.
public class MyWrapper { // does not extend Base
private Base delegate;
public MyWrapper(Base delegate) {
this.delegate = delegate;
}
public void foo() {
delegate.foo()
}
// does not have to implement bar()
}
If you don't need your delegator to be an actual instance of the base class, you can simply remove that relation:
public class MyWrapper {
private Base delegate;
public MyWrapper(Base delegate) {
this.delegate = delegate;
}
public void foo() {
delegate.foo()
}
}
Whether that works for you is highly dependent on your other code, and your needs aren't completely clear to me right now.
If the library defines an interface providing the public method which is implemented by the abstract base class, you could sensibly implement that interface without inheriting from the abstract base class, which might also satisfy your needs.
I have following abstract class:
public abstract class AbstractCreateActionHandler {
protected IWorkItem mCurrentWI;
public AbstractCreateActionHandler(IWorkItem wi) {
this.mCurrentWI = wi;
}
public final void invoke() {
try {
if (checkForLockingFile()) {
this.executeAction();
Configuration.deleteInstance();
}
} catch (IOException e) {
Configuration.deleteInstance();
e.printStackTrace();
}
}
protected abstract void executeAction();
private boolean checkForLockingFile() throws IOException {
String path = Configuration.getInstance().getProperty("path");
File lock = new File(path + "lock_"+mCurrentWI.getId()+"__.tmp");
if(!lock.exists()) {
lock.createNewFile();
return true;
}
return false;
}
}
A sub class extends the abstract class:
public class MyAction extends AbstractCreateActionHandler {
public MyAction(IWorkItem wi) {
super(wi);
}
#Override
protected void executeAction() {
// Implementation
}
// ALSO POSSIBLE...
/* #Override
public void executeAction() {
// Implementation
}*/
}
Question:
Is it possible that a developer which extends the abstract class and implements executeAction() method is not allowed the change the visibilty of executeAction()?
At the moment a developer can simply change the visibilty of the method to "public", create an object of the subclass and invoke executeExtion(). The visibility modifier can be changed and the abstract method is still accepted as "implemented".
So the "normal" calling sequence and checks which are executed in abstract class method invoke() can be bypassed. Is there a way to check if the invoke() method was called?
No, there's not really a way to restrict that. are you worried about malicious developers or clueless coworkers? if the latter then you just need to establish coding conventions like "don't increase the visibility of methods" and put some javadoc on the abstract method indicating proper usage. if the former, then you probably need to design your code differently (possibly using the strategy pattern).
Is it possible that a developer which extends the abstract class and implements executeAction() method is not allowed the change the visibilty of executeAction()?
No, this is not possible.
Chapter 8.4.8.3. Requirements in Overriding and Hiding of the Java Language Specification specifies:
The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, as follows: ...
So it is always possible to have the overriding method provide more access than the overridden method in the parent class.
See also java access modifiers and overriding methods.
It is allowed to change the modifier to public because it does not violate the Liskov Substitution Principle.
So the "normal" calling sequence and checks which are executed in
abstract class method invoke() can be bypassed. Is there a way to
check if the invoke() method was called?
If you pass someone the reference to AbstractCreateActionHandler then the caller will not be able to see the method executeAction as it is not public in AbstractCreateActionHandler class. So the caller will not be able to bypass execution sequence if you pass reference to Base class to caller. If you pass reference to Concrete class then the sequence can be broken.