Interceptor is not triggered from another EJB method in same EJB - java

Scenario
2x same Interceptor in same EJB on 2 methods:
...
#Interceptors(PerformanceAuditor.class)
public Date refreshIfNecessary() {
// there is also the PerformanceAuditor-Interceptor on this method
Pair<Date,String> lastImportDate = importDbDAO.findLatestImportLog();
someContainer.reloadIfNecessary(lastImportDate);
return lastImportDate.getLeft();
}
#Interceptors(PerformanceAuditor.class)
public boolean checkAndRefreshIfNecessary(final Date importDate) {
Date lastImportDate = refreshIfNecessary();
return lastImportDate.after(importDate);
}
...
Now we call on this EJB the methods externally with the following outcome:
calling refreshIfNecessary() -> PerformanceAuditor is called 2 times
calling checkAndRefreshIfNecessary() -> PerformanceAuditor is called also 2 times!
(but expected 3 times since one nesting level more!)
So what's happening here?

The answer is simple:
Interceptors "trigger" only if called as an "EJB call" (i.e. via their EJB interface). But in checkAndRefreshIfNecessary() the call of checkAndRefreshIfNecessary() is a simple Java method call and therefor not noticed by the container.
Solution: To call a method in an EJB internally as EJB call you have to go via its Interface which can be accessed e.g. via injected SessionContext and then via
context.getEJBLocalObject()... But this is certainly no a pretty solution! Better rethink your design in such cases!
PS: That's a beautiful example that one has still to understand the internals of an application server. Unfortunately from EJB3 onwards most features are so easy to use that more and more developers will not be confronted with the internals which will lead more often to such errors or at least bad design...

Related

CDI 1.X asynchronous events

I was looking at this project https://github.com/MSzturc/cdi-async-events-extension/,
which provides async events in CDI 1.X (built-in async came from 2.0).
Now I'm questioning this piece of code inside the custom Extension:
public <X> void processAnnotatedType(#Observes ProcessAnnotatedType<X> event, final BeanManager beanManager) {
final AnnotatedType<X> type = event.getAnnotatedType();
for (AnnotatedMethod<?> method : type.getMethods()) {
for (final AnnotatedParameter<?> param : method.getParameters()) {
if (param.isAnnotationPresent(Observes.class) && param.isAnnotationPresent(Async.class)) {
asyncObservers.add(ObserverMethodHolder.create(this.pool, beanManager, type, method, param));
}
}
}
}
public void afterBeanDiscovery(#Observes AfterBeanDiscovery event) {
for (ObserverMethod<?> om : this.asyncObservers) {
event.addObserverMethod(om);
}
}
Basically, while each Bean is being registered, it is looking at each method to see if a parameter has the #Async annotation.
Then, after the discovery step, it is registering the #Observes #Async methods.
Looking inside the addObserverMethod() method, provided by JBoss Weld 2, I see:
additionalObservers.add(observerMethod);
My question then is, wouldn't those methods be called twice? I mean, they may be registered twice, first by the container itself, then by calling the addObserverMethod() method.
I am not familiar with project, but from the first look it seems pretty outdated and not maintained.
As for the extension - it basically adds the "same" observer method (OM) again, with it's own OM implementation. So I would say the behaviour depends on CDI implementation as the spec does not guarantee what happens when you register "the same" OM again - is it replaced or is it just added like you say?
And by "the same" I mean the exact same underlying Java method although wrapped in a fancier coat.
Ultimately, you can easily try it and see for yourself, but I would advise against using that project as any problems you bump into are unlikely to be resolved on the project side.

Overriding/Wrapping spring beans in java based config multiple times

I have a (web-)application that needs special configurations and/or extensions based on the customer using the application. I call these additions "plugins" and they are auto discovered by classpath scanning when the application starts. For extensions that is incredibly easy. Let's say I want to have a plugin which adds an API that prints "hello world" when the URL /myplugin/greet is called: I just create a #Controller annotated class with the according #RequestMapping, put this in a myplugin.jar, copy that on the classpath and that's it.
Problems come up when I want to change some defaults and especially if I want to do this multiple times. Let's say my core application has a config like this:
#Configuration
public class CoreConfiguration {
#Bean
public Set<String> availableModules() {
return Collections.singleton("core");
}
}
Now I have two plugins that don't know about each other (but they do know the CoreConfig), but they both want to add themselves to the list of available modules. How would I do that? If I only had a single plugin that wants to override the module list I could override the existing bean from CoreConfiguration, but with two plugins that becomes a problem. What I imagine is something like this:
#Configuration
public class FirstPluginConfiguration {
#Bean
public Set<String> availableModules(Set<String> availableModules) {
Set<String> extendedSet = new HashSet<>(availableModules);
extendedSet.add("FirstPlugin");
return extendedSet;
}
}
Of course a SecondPluginConfiguration would look nearly exactly like this, except that the Set is not extended by "FirstPlugin", but by "SecondPlugin". I tested it to check what would happen and spring will just never call the First/SecondPluginConfiguration "availableModules" methods but it does not show an error either.
Now of course in this case this could easily be solved by using a mutable Set in the CoreConfiguration and then autowiring and extending the set in the other configurations, but for example I also want to be able to add method interceptors to some beans. So for example I might have an interface CrashLogger which has a logCrash(Throwable t) method and in CoreConfiguration a ToFileCrashLogger is created that writes stack traces to files as the name suggests. Now a plugin could say that he also wants to get notified about crashes, for example the plugin wants to ADDITIONALLY send the stacktrace to someone by email. For that matter that plugin could wrap the CrashLogger configured by the CoreConfiguration and fire BOTH. A second plugin could wrap the wrapper again and do something totally different with the stacktrace and still call both of the other CrashLoggers.
The later does sound somewhat like AOP and if I'd just let ALL my beans be proxied (I did not test that) I could autowire them into my plugin configurations, cast them to org.springframework.aop.framework.Advised and then add advices that manipulate behaviour. However it does seem like a huge overkill to generate proxies for each and everyone of my beans just so that that plugin can potentially add one or two advices one one or two beans.

How to get a new Iterable for every call on Stateless EJB

I'm querying a DB in this EJB. Result is Iterable (I can't change that).
But since the EJB is #Stateless it will "reuse" the Iterable<>, and the query result just gets added to it. Instead of being a "new" one!
How could i avoid that ?
I don't know if there a "fix" on the Iterable or is there something to be done with the SessionBean? Is this a bad combination?
#Stateless
public class StartSessionBean implements Serializable, StartSessionBeanLocal {
...
public Iterable<VType> resultQuery;
...
public List<VType> queryThis(String this) {
...
resultQuery = (Iterable<Type>) "query DB";
//Do Things here
return something;
}
}
You cannot maintain state such as public Iterable<VType> resultQuery; in a stateless session bean. That is what "stateless" means.
In practice what actually happens varies from implementation to implementation. Some will give you a brand new bean each time you call it. Others will select one from a pool and give you that one, with the result that each client may get another's instance of resultQuery.
If you want to maintain state in the EJB then you must use a #Stateful session bean.
Edit: You should not need to maintain the resultQuery field anyway. Just make it a local in your method implementation. Presumably you're using it in a for-each loop as that is what they're for.

I can't unit test my class without exposing private fields -- is there something wrong with my design?

I have written some code which I thought was quite well-designed, but then I started writing unit tests for it and stopped being so sure.
It turned out that in order to write some reasonable unit tests, I need to change some of my variables access modifiers from private to default, i.e. expose them (only within a package, but still...).
Here is some rough overview of my code in question. There is supposed to be some sort of address validation framework, that enables address validation by different means, e.g. validate them by some external webservice or by data in DB, or by any other source. So I have a notion of Module, which is just this: a separate way to validate addresses. I have an interface:
interface Module {
public void init(InitParams params);
public ValidationResponse validate(Address address);
}
There is some sort of factory, that based on a request or session state chooses a proper module:
class ModuleFactory {
Module selectModule(HttpRequest request) {
Module module = chooseModule(request);// analyze request and choose a module
module.init(createInitParams(request)); // init module
return module;
}
}
And then, I have written a Module that uses some external webservice for validation, and implemented it like that:
WebServiceModule {
private WebServiceFacade webservice;
public void init(InitParams params) {
webservice = new WebServiceFacade(createParamsForFacade(params));
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
So basically I have this WebServiceFacade which is a wrapper over external web service, and my module calls this facade, processes its response and returns some framework-standard response.
I want to test if WebServiceModule processes reponses from external web service correctly. Obviously, I can't call real web service in unit tests, so I'm mocking it. But then again, in order for the module to use my mocked web service, the field webservice must be accessible from the outside. It breaks my design and I wonder if there is anything I could do about it. Obviously, the facade cannot be passed in init parameters, because ModuleFactory does not and should not know that it is needed.
I have read that dependency injection might be the answer to such problems, but I can't see how? I have not used any DI frameworks before, like Guice, so I don't know if it could be easily used in this situation. But maybe it could?
Or maybe I should just change my design?
Or screw it and make this unfortunate field package private (but leaving a sad comment like // default visibility to allow testing (oh well...) doesn't feel right)?
Bah! While I was writing this, it occurred to me, that I could create a WebServiceProcessor which takes a WebServiceFacade as a constructor argument and then test just the WebServiceProcessor. This would be one of the solutions to my problem. What do you think about it? I have one problem with that, because then my WebServiceModule would be sort of useless, just delegating all its work to another components, I would say: one layer of abstraction too far.
Yes, your design is wrong. You should do dependency injection instead of new ... inside your class (which is also called "hardcoded dependency"). Inability to easily write a test is a perfect indicator of a wrong design (read about "Listen to your tests" paradigm in Growing Object-Oriented Software Guided by Tests).
BTW, using reflection or dependency breaking framework like PowerMock is a very bad practice in this case and should be your last resort.
I agree with what yegor256 said and would like to suggest that the reason why you ended up in this situation is that you have assigned multiple responsibilities to your modules: creation and validation. This goes against the Single responsibility principle and effectively limits your ability to test creation separately from validation.
Consider constraining the responsibility of your "modules" to creation alone. When they only have this responsibility, the naming can be improved as well:
interface ValidatorFactory {
public Validator createValidator(InitParams params);
}
The validation interface becomes separate:
interface Validator {
public ValidationResponse validate(Address address);
}
You can then start by implementing the factory:
class WebServiceValidatorFactory implements ValidatorFactory {
public Validator createValidator(InitParams params) {
return new WebServiceValidator(new ProdWebServiceFacade(createParamsForFacade(params)));
}
}
This factory code becomes hard to unit-test, since it is explicitly referencing prod code, so keep this impl very concise. Put any logic (like createParamsForFacade) on the side, so that you can test it separately.
The web service validator itself only gets the responsibility of validation, and takes in the façade as a dependency, following the Inversion of Control (IoC) principle:
class WebServiceValidator implements Validator {
private final WebServiceFacade facade;
public WebServiceValidator(WebServiceFacade facade) {
this.facade = facade;
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
Since WebServiceValidator is not controlling the creation of its dependencies anymore, testing becomes a breeze:
#Test
public void aTest() {
WebServiceValidator validator = new WebServiceValidator(new MockWebServiceFacade());
...
}
This way you have effectively inverted the control of the creation of the dependencies: Inversion of Control (IoC)!
Oh, and by the way, write your tests first. This way you will naturally gravitate towards a testable solution, which is usually also the best design. I think that this is due to the fact that testing requires modularity, and modularity is coincidentally the hallmark of good design.

Inside Interceptor.intercept(), how do I know if the Action has already been executed?

I'm implementing some stuff in my Struts-based application using interceptors, and I'm getting confused about how their lifecycle works. According to the Struts docs ("Interceptors", "Writing interceptors" and "Big picture"), it should work something like this:
FirstInterceptor
NextInterceptor
LastInterceptor
Action
Result
LastInterceptor
NextInterceptor
FirstInterceptor
which makes sense, but I'm stumbling on how to distinguish an interceptor call executing before the action from one executing after the result is rendered (I'm skipping PreResultListeners here). If I fire up a debugger, I get two calls to intercept() and can't find anything too obvious on the ActionInvocation I'm being passed. (Update: This part was a major confusion on my end, and I was able to answer my question below once I got it)
The "Big picture" page talks somewhat confusingly of a "before" and "after" "clause" that are called, but I don't know what to make of it:
[...]
This includes invoking any Interceptors (the before clause) in advance of invoking the Action itself.
[...]
Interceptors are executed again (in reverse order, calling the after clause).
[...]
(Update: These two sentences are still bad, though)
There's no two calls to the interceptor:
public class MyInterceptor implements Interceptor {
public String intercept(ActionInvocation invocation) {
/*
This is before Action.execute(),
and before all interceptors down the stack
*/
String code = invocation.invoke();
/*
This is after Action.execute(),
the result rendering and all
interceptors down the stack,
but before the interceptors
higher up in the stack.
*/
return code;
}
}
(Note that the "two calls to intercept" I was witnessing in the debugger were a result of a less obvious redirect that I failed to notice. This confused me a lot.)

Categories

Resources