Castle Windsor 3 Interceptor not releasing components created by a typed factory but 2.5.4 did. Why? - castle-windsor

This is a similar pattern to ones stated elsewhere and detailed in this blog post. I have this working using Windsor 2.5.4 pretty much as stated in the blogpost, but decided to switch to using Windsor 3. When I did this I noticed that the memory usage of the application go up over time - I guessed this would be that components were'nt being released.
There were a couple of modifications to the code in the blogpost, which may have caused the behaviour to differ.
Here is my AutoRelease interceptor (straight out of the blogpost, here for convenience and the lazy ;) )
[Transient]
public class AutoReleaseHandlerInterceptor : IInterceptor
{
private static readonly MethodInfo Execute = typeof(IDocumentHandler).GetMethod("Process");
private readonly IKernel _kernel;
public AutoReleaseHandlerInterceptor(IKernel kernel)
{
_kernel = kernel;
}
public void Intercept(IInvocation invocation)
{
if (invocation.Method != Execute)
{
invocation.Proceed();
return;
}
try
{
invocation.Proceed();
}
finally
{
_kernel.ReleaseComponent(invocation.Proxy);
}
}
}
One of my deviations from the blog post is the selector that the typed factory uses:-
public class ProcessorSelector : DefaultTypedFactoryComponentSelector
{
protected override Func<IKernelInternal, IReleasePolicy, object> BuildFactoryComponent(MethodInfo method,
string componentName,
Type componentType,
IDictionary additionalArguments)
{
return new MyDocumentHandlerResolver(componentName,
componentType,
additionalArguments,
FallbackToResolveByTypeIfNameNotFound,
GetType()).Resolve;
}
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return null;
}
protected override Type GetComponentType(MethodInfo method, object[] arguments)
{
var message = arguments[0];
var handlerType = typeof(IDocumentHandler<>).MakeGenericType(message.GetType());
return handlerType;
}
}
What might be noticeable is that I do not use the default resolver. (This is where, perhaps, the problem lies...).
public class MyDocumentHandlerResolver : TypedFactoryComponentResolver
{
public override object Resolve(IKernelInternal kernel, IReleasePolicy scope)
{
return kernel.Resolve(componentType, additionalArguments, scope);
}
}
(I omitted the ctor for brevity- nothing special happens there, it just calls the base ctor).
The reason I did this was because the default resolver would try to resolve by name and not by Type- and fail. In this case, I know I only ever need to resolve by type, so I just overrode the Resolve method.
The final piece of the puzzle will be the installer.
container.AddFacility<TypedFactoryFacility>()
.Register(
Component.For<AutoReleaseHandlerInterceptor>(),
Component.For<ProcessorSelector>().ImplementedBy<ProcessorSelector>(),
Classes.FromAssemblyContaining<MessageHandler>()
.BasedOn(typeof(IDocumentHandler<>))
.WithService.Base()
.Configure(c => c.LifeStyle.Is(LifestyleType.Transient)),
Component.For<IDocumentHandlerFactory>()
.AsFactory(c => c.SelectedWith<ProcessorSelector>()));
Stepping through the code, the interceptor is called and the finally clause is executed (e.g. I didn't get the method name wrong). However, the component does not seem to be released (using the performance counter shows this. Each invocation of the factory's create method increases the counter by one).
So far, my workaround has been to add a void Release(IDocumentHandler handler) method to my factory interface, and then after it executes the handler.Process() method, it explicitly releases the handler instance, and this seems to do the job- the performance counter goes up, and as the processing is done, it goes down).
Here is the factory:
public interface IDocumentHandlerFactory
{
IDocumentHandler GetHandlerForDocument(IDocument document);
void Release(IDocumentHandler handler);
}
And here is how I use it:
IDocumentHandlerFactory handler = _documentHandlerFactory.GetHandlerForDocument(document);
handler.Process();
_documentHandlerFactory.Release(handler);
Doing the Release explicitly therefore negates the need for the interceptor, but my real question is why this behaviour differs between the releases?

Note to self:- RTFM. Or in fact, read the Breakingchanges.txt file.
Here's the change that affects this behaviour (emphasis is mine):-
change - IReleasePolicy interface has a new method: IReleasePolicy
CreateSubPolicy(); usage of sub-policies changes how typed factories
handle out-of-band-release of components (see description)
impact - medium fixability - easy
description - This was added as an attempt to enable more fine grained
lifetime scoping (mostly for per-typed-factory right now, but in the
future also say - per-window in client app). As a side-effect of that
(and change to release policy behavior described above) it is no
longer possible to release objects resolved via typed factories, using
container.Release. As the objects are now tracked only in the scope
of the factory they will be released only if a call to factory
releasing method is made, or when the factory itself is released.
fix - Method should return new object that exposes the same behavior
as the 'parent' usually it is just best to return object of the same
type (as the built-in release policies do).
I didn't find the fix suggestion terribly helpful in my instance, however my solution in the question is what you should actually do (release using the factory). I'll leave it up in case anyone else has this (non) issue.

Related

Unable to mock the local variable inside a method in java [duplicate]

I'm using Mockito 1.9.0. I want mock the behaviour for a single method of a class in a JUnit test, so I have
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
The problem is, in the second line, myClassSpy.method1() is actually getting called, resulting in an exception. The only reason I'm using mocks is so that later, whenever myClassSpy.method1() is called, the real method won't be called and the myResults object will be returned.
MyClass is an interface and myInstance is an implementation of that, if that matters.
What do I need to do to correct this spying behaviour?
Let me quote the official documentation:
Important gotcha on spying real objects!
Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
In your case it goes something like:
doReturn(resultsIWant).when(myClassSpy).method1();
In my case, using Mockito 2.0, I had to change all the any() parameters to nullable() in order to stub the real call.
My case was different from the accepted answer. I was trying to mock a package-private method for an instance that did not live in that package
package common;
public class AnimalĀ {
void packageProtected();
}
package instances;
class Dog extends Animal { }
and the test classes
package common;
public abstract class AnimalTest<T extends Animal> {
#Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
#Test
public void myTest(){}
}
The compilation is correct, but when it tries to setup the test, it invokes the real method instead.
Declaring the method protected or public fixes the issue, tho it's not a clean solution.
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito version: 1.10.19.
I am very much a Mockito newb, so can't explain the following behaviour: if there's an expert out there who can improve this answer, please feel free.
The method in question here, getContentStringValue, is NOT final and NOT static.
This line does call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
This line does not call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
For reasons which I can't answer, using isA() causes the intended (?) "do not call method" behaviour of doReturn to fail.
Let's look at the method signatures involved here: they are both static methods of Matchers. Both are said by the Javadoc to return null, which is a little difficult to get your head around in itself. Presumably the Class object passed as the parameter is examined but the result either never calculated or discarded. Given that null can stand for any class and that you are hoping for the mocked method not to be called, couldn't the signatures of isA( ... ) and any( ... ) just return null rather than a generic parameter* <T>?
Anyway:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
The API documentation does not give any clue about this. It also seems to say the need for such "do not call method" behaviour is "very rare". Personally I use this technique all the time: typically I find that mocking involves a few lines which "set the scene" ... followed by calling a method which then "plays out" the scene in the mock context which you have staged... and while you are setting up the scenery and the props the last thing you want is for the actors to enter stage left and start acting their hearts out...
But this is way beyond my pay grade... I invite explanations from any passing Mockito high priests...
* is "generic parameter" the right term?
One more possible scenario which may causing issues with spies is when you're testing spring beans (with spring test framework) or some other framework that is proxing your objects during test.
Example
#Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
In above code both Spring and Mockito will try to proxy your MonitoringDocumentsRepository object, but Spring will be first, which will cause real call of findMonitoringDocuments method. If we debug our code just after putting a spy on repository object it will look like this inside debugger:
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
#SpyBean to the rescue
If instead #Autowired annotation we use #SpyBean annotation, we will solve above problem, the SpyBean annotation will also inject repository object but it will be firstly proxied by Mockito and will look like this inside debugger
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
and here is the code:
#SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
Important gotcha on spying real objects
When stubbing a method using spies , please use doReturn() family of methods.
when(Object) would result in calling the actual method that can throw exceptions.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
I've found yet another reason for spy to call the original method.
Someone had the idea to mock a final class, and found about MockMaker:
As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line: mock-maker-inline
Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
After I merged and brought that file to my machine, my tests failed.
I just had to remove the line (or the file), and spy() worked.
One way to make sure a method from a class is not called is to override the method with a dummy.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
#Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
As mentioned in some of the comments, my method was "static" (though being called on by an instance of the class)
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
Work around was make an instance method or upgrade Mockito to a newer version with some config: https://stackoverflow.com/a/62860455/32453
Bit late to the party but above solutions did not work for me , so sharing my 0.02$
Mokcito version: 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
Following did NOT work for me (actual method was being called):
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
Following WORKED:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());

Can't call component method from Castle Windsor OnCreate

I'm using Castle Windsor, which generally rocks, however I want it to call a method on my component when it is created and seem to have hit a limitation with OnCreate. For exaxmple:
interface IService1
{
void op1();
}
interface IService2
{
void op2();
}
class MyComponent : IService1, IService2
{
public void Init() // not part of either service
{
}
public void op1()
{
}
public void op2()
{
}
}
// I want to call the component's Init() method when it's created, which isn't part of the service contract
container.Register(Component.For<IService1, IService2>().ImplementedBy<MyComponent>().OnCreate(s => s.Init()));
// I could call something from IService1
container.Register(Component.For<IService1, IService2>().ImplementedBy<MyComponent>().OnCreate(s => s.op1()));
// But I can't call anything from any of the other services
container.Register(Component.For<IService1, IService2>().ImplementedBy<MyComponent>().OnCreate(s => s.op2()));
The first registration won't compile, complaining that it "cannot resolve symbol Init" because the instance passed to the delegate is of type IService1. OnCreate seems a bit limited to me, as in the third case when there are multiple services exposed it only allows you to bind to the first one you declare. I'd have to swap IService1 and IService2 around in order to call op2, but that's just moving the problem around.
Why isn't the type passed in the delegate that of the component being registered? Then I'd be free to call whatever method I like. Is there a way around this? Assume I can't put the Init() code in the component's constructor.
Don't be constrained by the strongly typed nature of C#
Yes, the way the API is constructed it's based off of the first service of the component but you can always cast it down to its actual type (or a secondary service)
.OnCreate(s => ((MyComponent)s).Init())
Alternatively, implement Castle.Core.IInitializable or System.ComponentModel.ISupportInitialize (if you don't want your components to reference Windsor) and then you won't need .OnCreate() at all.
For future reference, here's the relevant documentation.

PowerMock: mock out private static final variable, a concrete example

what is the absolute minimal mocking that must be done to pass this test?
code:
class PrivateStaticFinal {
private static final Integer variable = 0;
public static Integer method() { return variable + 1; }
}
test:
#RunWith(PowerMockRunner.class)
#PrepareForTest(PrivateStaticFinal.class)
class PrivateStaticFinalTest {
#Test
public void testMethod() {
//TODO PrivateStaticFinal.variable = 100
assertEquals(PrivateStaticFinal.method(), 101);
}
}
related: Mock private static final variables in the testing class (no clear answer)
Disclaimer: After a lot of hunting around on various threads I have found an answer. It can be done, but the general concensus is that it is not very safe but seeing as how you are doing this ONLY IN UNIT TESTS, I think you accept those risks :)
The answer is not Mocking, since most Mocking does not allow you to hack into a final. The answer is a little more "hacky", where you are actually modifying the private field when Java is calling is core java.lang.reflect.Field and java.lang.reflect.Modifier classes (reflection). Looking at this answer I was able to piece together the rest of your test, without the need for mocking that solves your problem.
The problem with that answer is I was running into NoSuchFieldException when trying to modify the variable. The help for that lay in another post on how to access a field that was private and not public.
Reflection/Field Manipulation Explained:
Since Mocking cannot handle final, instead what we end up doing is hacking into the root of the field itself. When we use the Field manipulations (reflection), we are looking for the specific variable inside of a class/object. Once Java finds it we get the "modifiers" of it, which tell the variable what restrictions/rules it has like final, static, private, public, etc. We find the right variable, and then tell the code that it is accessible which allows us to change these modifiers. Once we have changed the "access" at the root to allow us to manipulate it, we are toggling off the "final" part of it. We then can change the value and set it to whatever we need.
To put it simply, we are modifying the variable to allow us to change its properties, removing the propety for final, and then changing the value since it is no longer final. For more info on this, check out the post where the idea came from.
So step by step we pass in the variable we want to manipulate and...
// Mark the field as public so we can toy with it
field.setAccessible(true);
// Get the Modifiers for the Fields
Field modifiersField = Field.class.getDeclaredField("modifiers");
// Allow us to change the modifiers
modifiersField.setAccessible(true);
// Remove final modifier from field by blanking out the bit that says "FINAL" in the Modifiers
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// Set new value
field.set(null, newValue);
Combining this all into a new SUPER ANSWER you get.
#RunWith(PowerMockRunner.class)
#PrepareForTest()
class PrivateStaticFinalTest {
#Test
public void testMethod(){
try {
setFinalStatic(PrivateStaticFinal.class.getDeclaredField("variable"), Integer.valueOf(100));
}
catch (SecurityException e) {fail();}
catch (NoSuchFieldException e) {fail();}
catch (Exception e) {fail();}
assertEquals(PrivateStaticFinal.method(), Integer.valueOf(101));
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
// remove final modifier from field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
}
Update
The above solution will work only for those constants which is initialized in static block.When declaring and initializing the constant at the same time, it can happen that the compiler inlines it, at which point any change to the original value is ignored.

Intercepting the concrete implementation (as opposed to service) using Castle Windsor

I'm experimenting with interception in Castle Windsor and notice that interceptors seem to be created as decorators of my service interface.
In other words, if I have an interface "ISomethingDoer" and a concrete "ConcreteSomethingDoer", the proxy implements ISomethingDoer but does not inherit from ConcreteSomethingDoer.
This is fine, and no doubt by design, but what I'm wondering is whether I can intercept protected virtual methods in my concrete classes that wouldn't be known by the public interface. I am doing this in order to add logging support, but I might want to log some of the specific internal details of a class.
In my slightly unimaginative test case I have this:
public interface ISomethingDoer
{
void DoSomething(int Count);
}
[Loggable]
public class ConcreteSomethingDoer : ISomethingDoer
{
public void DoSomething(int Count)
{
for (var A = 0; A < Count; A++)
{
DoThisThing(A);
}
}
[Loggable]
protected virtual void DoThisThing(int A)
{
("Doing a thing with " + A.ToString()).Dump();
}
}
So what I want to do is log calls to "DoThisThing" even though it's not part of the interface.
I've managed to get this working in Autofac. (I've created a Linqpad script here: http://share.linqpad.net/frn5a2.linq) but am struggling with Castle Windsor (see http://share.linqpad.net/wn7877.linq)
In both cases my interceptor is the same and looks like this:
public class Logger : IInterceptor
{
public void Intercept(IInvocation Invocation)
{
String.Format("Calling method {0} on type {1} with parameters {2}",
Invocation.Method.Name,
Invocation.InvocationTarget.GetType().Name,
String.Join(", ", Invocation.Arguments.Select(a => (a ?? "*null*").ToString()).ToArray())).Dump();
Invocation.Proceed();
"Done".Dump();
}
}
What I really want to do is say "any classes with a [Loggable] attribute, should use the logging interceptor". In the Autofac example I've specifically attached a logger to the registration, whereas with Castle I'm using an IModelInterceptorsSelector which looks like this:
public class LoggerInterceptorSelector : IModelInterceptorsSelector
{
public bool HasInterceptors(ComponentModel Model)
{
return Model.Implementation.IsDefined(typeof(LoggableAttribute), true);
}
public InterceptorReference[] SelectInterceptors(ComponentModel Model, InterceptorReference[] Interceptors)
{
return new[]
{
InterceptorReference.ForType<Logger>()
};
}
}
Finally, the code to execute all this is:
var Container = new WindsorContainer();
Container.Register(
Component.For<Logger>().LifeStyle.Transient
);
Container.Kernel.ProxyFactory.AddInterceptorSelector(new LoggerInterceptorSelector());
Container.Register(
Component.For<ISomethingDoer>()
.ImplementedBy<ConcreteSomethingDoer>()
.LifeStyle.Transient
);
var Doer = Container.Resolve<ISomethingDoer>();
Doer.DoSomething(5);
When run I would expect to see "Calling method DoThisThing with parameters x" for each time the method is called. Instead I only get the call to DoSomething logged.
I can see why Castle Windsor is doing this, but I'm wondering if there is a way to tweak the behaviour?
(As a side-note I don't want to use Windsor's own interceptor attributes as I don't want to introduce dependencies to Castle outside of my composition root.)
I have tried resolving the ConcreteSomethingDoer specifically and this works, but not if I'm resolving the ISomethingDoer.
Apologies for the long post, and also apologies because I am pretty new to Castle Windsor!
I you could register like:
Container.Register(
Component.For<ISomethingDoer, ConcreteSomethingDoer>()
.ImplementedBy<ConcreteSomethingDoer>()
.LifeStyle.Transient
);
This should create a class proxy by deriving from ConcreteSomethingDoer. However this won't work with dynamic interceptors. However you probably can work around that by creating a facility which registers the interceptor when needed.

Can I have conditional construction of classes when using IoC.Resolve?

I have a service class which has overloaded constructors. One constructor has 5 parameters and the other has 4.
Before I call,
var service = IoC.Resolve<IService>();
I want to do a test and based on the result of this test, resolve service using a specific constructor. In other words,
bool testPassed = CheckCertainConditions();
if (testPassed)
{
//Resolve service using 5 paramater constructor
}
else
{
//Resolve service using 4 parameter constructor
//If I use 5 parameter constructor under these conditions I will have epic fail.
}
Is there a way I can specify which one I want to use?
In general, you should watch out for ambiguity in constructors when it comes to DI because you are essentially saying to any caller that 'I don't really care if you use one or the other'. This is unlikely to be what you intended.
However, one container-agnostic solution is to wrap the conditional implementation into another class that implements the same interface:
public class ConditionalService : IService
{
private readonly IService service;
public ConditionalService()
{
bool testPassed = CheckCertainConditions();
if (testPassed)
{
// assign this.service using 5 paramater constructor
}
else
{
// assign this.service using 4 parameter constructor
}
}
// assuming that IService has a Foo method:
public IBaz Foo(IBar bar)
{
return this.service.Foo(bar);
}
}
If you can't perform the CheckCertainConditions check in the constructor, you can use lazy evaluation instead.
It would be a good idea to let ConditionalService request all dependencies via Constructor Injection, but I left that out of the example code.
You can register ConditionalService with the DI Container instead of the real implementation.
My underlying problem was that I was trying to resolve my class which had the following signature:
public DatabaseSchemaSynchronisationService(IDatabaseService databaseService, IUserSessionManager userSessionManager)
This was basically useless to me because my usersessionmanager had no active NHibernate.ISession because a connection to my database had not yet been made. What I was trying to do was check if I did have a connection and only then resolve this class which served as a service to run database update scripts.
When changing my whole class to perform the scripts in a different way, all I needed in its constructor's signature was:
public DatabaseSchemaSynchronisationService(ISessionFactory sessionFactory)
This allowed me to open my own session. I did, however have to first check if the connection was ready before attempting to resolve the class, but having IDatabaseSchemaSynchronisationService as a parameter to another class's constructor; this class also gettting resolved somewhere where I could not check the db connection was a bad idea.
Instead in this second class, I took the IDatabaseSchemaSynchronisationService paramater out of the constructor signature and made it a local variable which only gets instantiated (resolved) :
if (connectionIsReady)
Thanks to everyone who answered.