Component creation fails when using #Reference on OSGi DS service - osgi

I am trying to get bind/unbind methods called on a DS component. I've reduced it to the simplest example that doesn't work.
If I remove the #Reference on the bind method then the test is successful. Obviously the log statements don't get called. Otherwise it fails on the AssertNotNull.
Any suggestions on what I'm doing wrong? What is the right way to add bind/unbind methods to a component?
Updated code to show correct approach.
Interface
public interface Foo {
public abstract String bar();
}
Class
#Component(immediate = true, enabled = true, service = Foo.class, scope = ServiceScope.SINGLETON)
public class FooImpl implements Foo {
private final static Logger logger = LoggerFactory.getLogger(FooImpl.class);
#Override
public String bar() {
return "bar";
}
#Activate
public synchronized void bind() {
logger.debug(String.format("bind called for %s", this.getClass().getName()));
}
#Deactivate
public synchronized void unbind(Foo service) {
logger.debug(String.format("unbind called for %s", this.getClass().getName()));
}
}
Generated component definition
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" activate="bindFoo" deactivate="unbindFoo" enabled="true" immediate="true" name="com.vogelware.experiment.FooImpl">
<service scope="singleton">
<provide interface="com.vogelware.experiment.Foo"/>
</service>
<implementation class="com.vogelware.experiment.FooImpl"/>
</scr:component>
Test class
class FooTest {
#Test
void test() throws InterruptedException {
ServiceTracker<Foo, Foo> testTracker = new ServiceTracker<Foo, Foo>(Activator.getContext(), Foo.class, null);
testTracker.open();
testTracker.waitForService(500);
Foo user = testTracker.getService();
testTracker.close();
assertNotNull(user); <= fails here
}
}

Your component is trying to use itself as a dependency. Thus you have an unsolvable circular reference. Your component cannot be satisfied (and thus registered as a Foo service) until its dependency on a Foo service (the #Reference) can be met.

The answer to my question is that in the 1.3 spec, use #Activate and #Deactivate. I've modified the original question to show the solution in code.
Check out http://blog.vogella.com/2016/06/21/getting-started-with-osgi-declarative-services/ for more details.

Related

Class fixture type 'SetupFixture' had one or more unresolved constructor arguments [duplicate]

I am using XUnit and need to perform some action before running a test suit. so, I try to use IClassFixture feature of XUnit. but I cannot find a way to inject dependencies into the Fixture class. my code structure is such as below:
public class MyFixture
{
IDependency _dep;
public MyFixture(IDependency dep)
{
_dep = dep;
}
void DoSomeJob()
{
//// some code there
dep.DoSome();
}
}
And this is my test class code:
public class MyTest : IClassFixture<MyFixture>
{
[Fact]
public void test_my_code()
{
////simply just test the code
}
}
but when I run the test I am getting the exception
Xunit.Sdk.TestClassException Class fixture type 'MyFixture' had one or more unresolved constructor
Your Fixture class depends on IDependency dep, which has not been configured. You could use the Fixture class to setup a service provider; However it is not the best solution, as you have to end up using service locator patter such as
serviceProvider.GetRequiredService<T>()
Suggest to use xunit.di, it is an extension built into xunit framework to support constructor dependency injection, which allows us to achieve Inversion of Control (IoC) between test classes and their dependencies.
Install-Package Xunit.Di
To use xunit.di:
Install the xunit.di nuget package
Create a Setup.cs class to configure dependencies, (optional) and inherits the Xunit.Di.Setup.cs
Configure dependencies in the Setup.cs class.
Find full instructions and demos from xunit.di GET-STARTED
Your test project has the following:
Setup class that has a public IServiceProvider, which configures all the dependencies
Test class with constructor injecting the dependencies
Your Setup.cs class looks like below:
private IServiceProvider _services;
private bool _built = false;
private readonly IHostBuilder _defaultBuilder;
public Setup()
{
_defaultBuilder = Host.CreateDefaultBuilder();
}
public IServiceProvider Services => _services ?? Build();
private IServiceProvider Build()
{
if (_built)
throw new InvalidOperationException("Build can only be called once.");
_built = true;
_defaultBuilder.ConfigureServices((context, services) =>
{
services.AddSingleton<TextReaderService>();
services.AddSingleton<IDependency, DependencyImpl>();
// where DependencyImpl implements IDependency
// ... add other services needed
});
_services = _defaultBuilder.Build().Services;
return _services;
}
Then your test class looks like below:
public class MyTest
{
private readonly IDependency _dependency;
public MyTest(IDependency dependency)
{
_dependency = dependency;
}
[Fact]
public void test_my_code()
{
var result = _dependency.DoStuff();
Assert.NotNull(result);
////simply just test the code
}
}

How do I mock an autowired #Value field in Spring with Mockito?

I'm using Spring 3.1.4.RELEASE and Mockito 1.9.5. In my Spring class I have:
#Value("#{myProps['default.url']}")
private String defaultUrl;
#Value("#{myProps['default.password']}")
private String defaultrPassword;
// ...
From my JUnit test, which I currently have set up like so:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "classpath:test-context.xml" })
public class MyTest
{
I would like to mock a value for my "defaultUrl" field. Note that I don't want to mock values for the other fields — I'd like to keep those as they are, only the "defaultUrl" field. Also note that I have no explicit "setter" methods (e.g. setDefaultUrl) in my class and I don't want to create any just for the purposes of testing.
Given this, how can I mock a value for that one field?
You can use the magic of Spring's ReflectionTestUtils.setField in order to avoid making any modifications whatsoever to your code.
The comment from Michał Stochmal provides an example:
use ReflectionTestUtils.setField(bean, "fieldName", "value"); before invoking your bean method during test.
Check out this tutorial for even more information, although you probably won't need it since the method is very easy to use
UPDATE
Since the introduction of Spring 4.2.RC1 it is now possible to set a static field without having to supply an instance of the class. See this part of the documentation and this commit.
It was now the third time I googled myself to this SO post as I always forget how to mock an #Value field. Though the accepted answer is correct, I always need some time to get the "setField" call right, so at least for myself I paste an example snippet here:
Production class:
#Value("#{myProps[‘some.default.url']}")
private String defaultUrl;
Test class:
import org.springframework.test.util.ReflectionTestUtils;
ReflectionTestUtils.setField(instanceUnderTest, "defaultUrl", "http://foo");
// Note: Don't use MyClassUnderTest.class, use the instance you are testing itself
// Note: Don't use the referenced string "#{myProps[‘some.default.url']}",
// but simply the FIELDs name ("defaultUrl")
You can use this magic Spring Test annotation :
#TestPropertySource(properties = { "my.spring.property=20" })
see
org.springframework.test.context.TestPropertySource
For example, this is the test class :
#ContextConfiguration(classes = { MyTestClass.Config.class })
#TestPropertySource(properties = { "my.spring.property=20" })
public class MyTestClass {
public static class Config {
#Bean
MyClass getMyClass() {
return new MyClass ();
}
}
#Resource
private MyClass myClass ;
#Test
public void myTest() {
...
And this is the class with the property :
#Component
public class MyClass {
#Value("${my.spring.property}")
private int mySpringProperty;
...
I'd like to suggest a related solution, which is to pass the #Value-annotated fields as parameters to the constructor, instead of using the ReflectionTestUtils class.
Instead of this:
public class Foo {
#Value("${foo}")
private String foo;
}
and
public class FooTest {
#InjectMocks
private Foo foo;
#Before
public void setUp() {
ReflectionTestUtils.setField(Foo.class, "foo", "foo");
}
#Test
public void testFoo() {
// stuff
}
}
Do this:
public class Foo {
private String foo;
public Foo(#Value("${foo}") String foo) {
this.foo = foo;
}
}
and
public class FooTest {
private Foo foo;
#Before
public void setUp() {
foo = new Foo("foo");
}
#Test
public void testFoo() {
// stuff
}
}
Benefits of this approach: 1) we can instantiate the Foo class without a dependency container (it's just a constructor), and 2) we're not coupling our test to our implementation details (reflection ties us to the field name using a string, which could cause a problem if we change the field name).
You can also mock your property configuration into your test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "classpath:test-context.xml" })
public class MyTest
{
#Configuration
public static class MockConfig{
#Bean
public Properties myProps(){
Properties properties = new Properties();
properties.setProperty("default.url", "myUrl");
properties.setProperty("property.value2", "value2");
return properties;
}
}
#Value("#{myProps['default.url']}")
private String defaultUrl;
#Test
public void testValue(){
Assert.assertEquals("myUrl", defaultUrl);
}
}
I used the below code and it worked for me:
#InjectMocks
private ClassABC classABC;
#Before
public void setUp() {
ReflectionTestUtils.setField(classABC, "constantFromConfigFile", 3);
}
Reference: https://www.jeejava.com/mock-an-autowired-value-field-in-spring-with-junit-mockito/
Also note that I have no explicit "setter" methods (e.g. setDefaultUrl) in my class and I don't want to create any just for the purposes of testing.
One way to resolve this is change your class to use Constructor Injection, that can be used for testing and Spring injection. No more reflection :)
So, you can pass any String using the constructor:
class MySpringClass {
private final String defaultUrl;
private final String defaultrPassword;
public MySpringClass (
#Value("#{myProps['default.url']}") String defaultUrl,
#Value("#{myProps['default.password']}") String defaultrPassword) {
this.defaultUrl = defaultUrl;
this.defaultrPassword= defaultrPassword;
}
}
And in your test, just use it:
MySpringClass MySpringClass = new MySpringClass("anyUrl", "anyPassword");
Whenever possible, I set the field visibility as package-protected so it can be accessed from the test class. I document that using Guava's #VisibleForTesting annotation (in case the next guy wonders why it's not private). This way I don't have to rely on the string name of the field and everything stays type-safe.
I know it goes against standard encapsulation practices we were taught in school. But as soon as there is some agreement in the team to go this way, I found it the most pragmatic solution.
Another way is to use #SpringBootTest annotation properties field.
Here we override example.firstProperty property:
#SpringBootTest(properties = { "example.firstProperty=annotation" })
public class SpringBootPropertySourceResolverIntegrationTest {
#Autowired private PropertySourceResolver propertySourceResolver;
#Test
public void shouldSpringBootTestAnnotation_overridePropertyValues() {
String firstProperty = propertySourceResolver.getFirstProperty();
String secondProperty = propertySourceResolver.getSecondProperty();
Assert.assertEquals("annotation", firstProperty);
Assert.assertEquals("defaultSecond", secondProperty);
}
}
As you can see It overrides only one property. Properties not mentioned in #SpringBootTest stay untouched. Therefore, this is a great solution when we need to override only specific properties for the test.
For single property you can write it without braces:
#SpringBootTest(properties = "example.firstProperty=annotation")
Answer from: https://www.baeldung.com/spring-tests-override-properties#springBootTest
I also encourage you to whenever possible pass property as a parameter in constructor like in Dherik answer (https://stackoverflow.com/a/52955459/1673775) as it enables you to mock properties easily in unit tests.
However in integration tests you often don't create objects manually, but:
you use #Autowired
you want to modify property used in a class that is used in your integration test indirectly as it is deep dependency of some directly used class.
then this solution with #SpringBootTest might be helpful.

How to choose spring configuration in runtime based on a tenant?

I would like to be able to choose specific Spring (or Grails) context configuration based on the tenant that user belongs to in runtime. Let's say I use Spring Security and I retrieve tenantId during login.
Imagine now I have a two tenants and they pay different commission. How to inject specific service into a controller without too much plumbing? Here are two different contexts. So, I should inject different ExchangeService based on tenant.
#Configuration
public class FooTenant{
#Bean
public ExchangeService bar() {
return new ZeroCommisionExchangeService ();
}
}
#Configuration
public class BarTenant{
#Bean
public ExchangeService bar() {
return new StandardCommisionExchangeService ();
}
}
Edit:
I am aware I can obtain reference to Spring context and ask for service "manually", but I am looking for a more generic solution where this problematic is solved by IoC framework.
A couple of years ago we needed somthing like this but only for DataSources and ViewResolvers. We developed a solution using spring' TargetSource solution. (Initially we used a HotswappableTargetSource but that wasn't adequate for our use-case.
The code we developed is availabe here in the multi-tenant directory.
It is fully configurable and flexible.
Basically what you do is you configura a ContextSwappableTargetSource and tell it what type of interface/class it needs to return.
<bean id="yourTentantBasedServiceId" class="biz.deinum.multitenant.aop.target.ContextSwappableTargetSource">
<constructor-arg value="ExchangeService" />
</bean>
The default is to lookup beans in the ApplicationContext based on the tenantId (see the BeanFactoryTargetRegistry for this). However you can specify one or more of those (we used a JndiLookupTargetRegistry to dynamically lookup datasource, which allowed use to add tenants on the fly without restarting the application).
If you explicitly configure a BeanFactoryTargetRegistry you can add a prefix and suffix.
<bean id="exchangeService" class="biz.deinum.multitenant.aop.target.ContextSwappableTargetSource">
<constructor-arg value="ExchangeService" />
<property name="targetRegistry>
<bean class="biz.deinum.multitenant.aop.target.registry.impl.BeanFactoryTargetRegistry">
<property suffix="ExchangeService"/>
</bean>
</property>
</bean>
Now for foo it would lookup a bean named fooExchangeService and for bar barExchangeService.
The tenantId is stored in a ThreadLocal which is wrapped inside the ContextHolder. You need to find a way to fill and clear this thread local (in general a servlet Filter does that trick.
In your code you can now simply use the interface ExchangeService and at runtime based on the tenantId the correct implemenation will be looked up.
Also see http://mdeinum.wordpress.com/2007/01/05/one-application-per-client-database/
Assuming you have different services already defined, you can get their bean from the context and use it. In my example, all the services have implementation of serviceMethod and based on some criteria pick your proper service. The only thing I am not sure is how Multitenancy might impact this.
import org.springframework.context.ApplicationContext
class ServiceManagerController {
def serviceManager
def index() {
ApplicationContext ctx = grails.util.Holders.grailsApplication.mainContext
serviceManager = ctx.getBean(params.serviceName); //firstService or secondService
render serviceManager.serviceMethod()
}
}
FirstService
class FirstService {
def serviceMethod() {
return "first"
}
}
SecondService:
class SecondService {
def serviceMethod() {
return "second"
}
}
While it is possible to swap beans instantiated in a spring context at runtime (HotswappableTargetSource), it is not meant for use cases such as yours.
Remember there is one Spring Context for your application, all threads use the same instances (in most cases), this implies when you swap out a bean implementation, you are affectively doing this for all your application's users. To prevent this, you run into issues of ensuring Thread Safety, employing Thread Locals, as listed in another answer.
While it is possible to continue this approach and arrive at an implementation that gets the job done, it would definitely be a very contrived way of solving this problem.
You should take a step back and look at your problem in a more wholesome, system wide design point of view. Bust out your patterns books and look at how this can be resolved, regardless of whether you use Spring or an other framework. Service Locator, Factory bean etc described in some of the answers above is a step in the correct direction.
Your Use Case is pretty common for multi-tenant applications. You need to narrow down things that are likely to change based on a tenantId versus things that are constant across.
For instance as mentioned in the question, each Tenant might have a different commission amount or even different algorithm for commission calculation. A simple solution to this would be to implement a CommissionCalculationService which accepts a tenantId, and any other domain object based on which commission is to be calculated, I would imagine this would be something like Order or Sale, whatever makes sense in your application.
You now need a CommissionServiceFactory or a ServiceLocator which will contain tenant specific implementations of the CommissionCalculationService. The Service Locator is instantiated when the Spring context loads, and is injected with implementation classes also at application startup.
When you want to calculate commission for a tenant, you basically obtain the tenantId from the user's login, pass the tenant id to your service locator, based on the tenantId passed, the service locator returns the appropriate instance of a Service Implementation. In your calling class, use this instance to calculate the commission for the tenant.
Another pattern to consider is the Strategy Pattern, or even Template Pattern.
Bottom line, even if you want tenant specific logic implemented cleanly, don't thing about changing the beans loaded in the context. Have classes in your context that can handle all your tenant specific logic. Rely on design patterns to use the correct bean from the context based on the tenant id.
I apologize if the answer was a little verbose, I felt it was needed to explain why I think updating beans in a loaded Spring Context is not the appropriate solution.
I use the following code:
public class ConfigurableProxyFactoryBean implements FactoryBean<Object>, BeanNameAware {
#Autowired
private ApplicationContextProvider applicationContextProvider;
private Class<?> proxyType;
private String beanName;
private Object object;
private Object fallbackObject;
private Object monitor = new Object();
private ConfigurableProxy proxy;
public ConfigurableProxyFactoryBean(Class<?> proxyType) {
this.proxyType = proxyType;
}
public Object getFallbackObject() {
return fallbackObject;
}
public void setFallbackObject(Object fallbackObject) {
synchronized (monitor) {
this.fallbackObject = fallbackObject;
if (proxy != null) {
proxy.setFallbackObject(fallbackObject);
}
}
}
#Override
public void setBeanName(String name) {
beanName = name;
}
#Override
public Object getObject() throws Exception {
synchronized (monitor) {
if (object == null) {
#SuppressWarnings("unchecked")
Class<Object> type = (Class<Object>)proxyType;
proxy = new ConfigurableProxy(applicationContextProvider, beanName);
proxy.setFallbackObject(fallbackObject);
object = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class<?>[] { type }, proxy);
}
return object;
}
}
#Override
public Class<?> getObjectType() {
return proxyType;
}
#Override
public boolean isSingleton() {
return true;
}
}
class ConfigurableProxy implements InvocationHandler {
public ConfigurableProxy(ApplicationContextProvider appContextProvider, String beanName) {
this.appContextProvider = appContextProvider;
this.beanName = beanName;
}
private ApplicationContextProvider appContextProvider;
private String beanName;
private Object fallbackObject;
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ApplicationContext appContext = appContextProvider.getApplicationContext();
String name = "$&&#" + beanName;
Object bean = appContext.containsBean(name) ? appContext.getBean(name) : fallbackObject;
return method.invoke(bean, args);
}
public void setFallbackObject(Object fallbackObject) {
this.fallbackObject = fallbackObject;
}
}
ApplicationContextProvider has implementation, that chooses ApplicationContext according to current tennant.
In XML configuration it is used like this:
<bean class="my.package.infrastructure.ConfigurableProxyFactoryBean" name="beanName">
<constructor-arg>
<value type="java.lang.Class">my.package.model.ServiceInterface</value>
</constructor-arg>
<property name="fallbackObject">
<bean class="my.package.service.DefaultServiceImplementation"/>
</property>
</bean>
And in tennant configuration that way:
<bean class="my.package.service.ServiceImplementationA" name="$&&#beanName"/>
To inject this service somewhere you just write:
public class MyController {
#Autowired
private ServiceInterface service;
}
Also you are to implement ApplicationContextProvider, I won't share mine. It is not very hard to implement. For example, your implementation can just store context in ThreadLocal. And you create your own ServletContextListener, which for every query gets the current tennant and stores it into your ApplicationContextProvider implementation.
The new tenant scope and a servicelocator can helps
Tenant scope will guarantee than service is created one time for a tenant
Sample code:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="tenant" value="foo.TenantScope"/>
</map>
</property>
</bean>
<bean id="service" class="foo.Service" factory-bean="tenantServiceLocator" factory-method="createInstance" scope="tenant"/>
<bean id="fooService" class="FooService">
<bean id="barService" class="BarService">
<bean id="tenantServiceLocator" class="foo.TenantServiceLocator">
<property name="services">
<map>
<entry key="foo" value-ref="fooService"/>
<entry key="bar" value-ref="barService"/>
</map>
</property>
</bean>
TenantServiceLocator should know the user tenantId
public class TenantServiceLocator {
private Map<String, Service> services;
public String getTenantId() {
return "foo"; // get it from user in session
}
public Map<String, Service> getServices() {
return services;
}
public void setServices(Map<String, Service> services) {
this.services = services;
}
public Service createInstance(){
return services.get(tenantId);
}
}
public class FooController{
#Autowired
private Service service;
}
A sample TenantScope implementation
public class TenantScope implements Scope {
private static Map<String, Map<String, Object>> scopeMap = new HashMap<String, Map<String, Object>>();
#Override
public Object get(String name, ObjectFactory<?> objectFactory) {
Map<String, Object> scope = getTenantScope(getTenantId());
Object object = scope.get(name);
if(object == null){
object = objectFactory.getObject();
scope.put(name, object);
}
return object;
}
private Map<String, Object> getTenantScope(String tenantId) {
if (!scopeMap.containsKey(tenantId)) {
scopeMap.put(tenantId, new HashMap<String, Object>());
}
return scopeMap.get(tenantId);
}
private String getTenantId() {
return "foo"; // load you tenantId
}
#Override
public Object remove(String name) {
Map<String, Object> scope = getTenantScope(getTenantId());
return scope.remove(name);
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
}
#Override
public Object resolveContextualObject(String key) {
return null;
}
#Override
public String getConversationId() {
return null;
}
}
Transforming my comment in an answer, one possible solution is to create a spring factory bean, that receive all he needs to decide which service needs to be returned when creating the instance.
Translating to Grails:
public interface ChoosableServiceIntf {
String getName();
}
class NormalService implements ChoosableServiceIntf {
public String getName() {
return getClass().name;
}
}
class ExtendedService implements ChoosableServiceIntf {
public String getName() {
return getClass().name
}
}
class ChoosableServiceFactory {
static ChoosableServiceIntf getInstance(String decisionParam) {
if(decisionParam == 'X') {
return applicationContext.getBean('extendedService')
}
return applicationContext.getBean('normalService')
}
static ApplicationContext getApplicationContext() {
return Holders.grailsApplication.mainContext
}
}
Here we have two services and ChoosableServiceFactory is responsible to know witch is the correct one.
Then you will need to use the method ApplicationContext#getBean(String, Object[]) to return the correct instance and will also make the factory prototyped scope because of the runtime params.
A controller to test it:
class MyController {
def grailsApplication
def index() {
ChoosableServiceIntf service = grailsApplication.mainContext.getBean('choosableServiceFactory', ["X"] as Object[])
ChoosableServiceIntf serviceNormal = grailsApplication.mainContext.getBean('choosableServiceFactory', ["N"] as Object[])
render text: "#1 - ${service.class.name} , #2 - ${serviceNormal.class.name}"
}
}
This will print #1 - dummy.ExtendedService , #2 - dummy.NormalService
The declaration of the beans will be:
choosableServiceFactory(ChoosableServiceFactory) { bean ->
bean.scope = 'prototype'
bean.factoryMethod = 'getInstance'
}
normalService(NormalService)
extendedService(ExtendedService)

JavaEE CDI in Weld: Generic Events?

I have an idea for a specific event handling based on generics, but seems like Weld can't handle them. I asked google but couldn't find an alternative CDI extension for this.
Question: is there a CDI extension, that can handle event propagation of generic-typed events?
In the following the explicit problem I have.
I have three general events, EntityCreated, EntityChanged and EntityDeleted. The base class for them is defined like this:
public abstract class DatabaseEvent<TargetType> {
public TargetType target;
public DatabaseEvent(TargetType target) {
this.target = target;
}
}
The events then are simple inherited classes:
public class EntityCreatedEvent<TargetType> extends DatabaseEvent<TargetType> {
public EntityCreatedEvent(TargetType target) {
super(target);
}
}
I fire them like this:
public abstract class MyHome<EntityType> {
private EntityType entity;
#Inject
Event<EntityCreatedEvent<EntityType>> entityCreatedEvent;
public void fireCreatedEvent() {
EntityCreatedEvent<EntityType> payload = new EntityCreatedEvent<EntityType>(entity);
entityCreatedEvent.fire(payload);
}
}
I want to observe them like this:
public void handleProjectCreated(#Observes EntityCreatedEvent<Project> event) { ... }
When launching the server Weld tells me it can't handle generic-typed events. The CDI-way of doing things would be to use additional qualifiers instead of the generics to distiguish them, e.g.:
public void handleProjectCreated(#Observes #ProjectEvent EntityCreatedEvent event) { ... }
However, I fire the events from that MyHome base class, where I can't just fire with the #ProjectEvent: it might not be a project but another type.
My solution up to now is to skip that typing altogether and handle them like this:
public void handleProjectCreated(#Observes EntityCreatedEvent event) {
if(event.target instanceof Project) { ... }
}
This solution is okay, but not perfect.
I guess you can do this with dinamically binding qualifier members. This is what your code would look like:
public abstract class MyHome {
private EntityType entity;
#Inject
Event<EntityCreatedEvent> entityCreatedEvent;
public void fireCreatedEvent() {
entityCreatedEvent.select(getTypeBinding()).fire(new EntityCreatedEvent(entity));
}
private TypeBinding getTypeBinding() {
return new TypeBinding() {
public Class<? extends EntityType> value() {return entity.getClass();}
};
}
#Qualifier
#Target({ PARAMETER, FIELD })
#Retention(RUNTIME)
public #interface EntityTypeQualifier {
Class<? extends EntityType> value();
}
public abstract class TypeBinding extends AnnotationLiteral<EntityTypeQualifier> implements EntityTypeQualifier {}
//Observers
public void handleEntityType1Created(#Observes #EntityTypeQualifier(EntityType1.class) EntityCreatedEvent event) {}
public void handleEntityType2Created(#Observes #EntityTypeQualifier(EntityType2.class) EntityCreatedEvent event) {}
As this CDI issue points it is not possible to fire an without having the type of T at runtime.
But, if you have the type of T (i.e. you have an instance) you can use the Event as an Instance, and select the event to be fired using a dynamic type literal.

PowerMock issue with an extended method

I am attempting to use PowerMock to mock some third party code and I am having an issue with an extended method.
So I will give a snippet showing what is occuring.
ClassA extends ClassB{
super();
}
ClassB extends ClassC{
super();
}
ClassC {
String methodA();
}
Now I am attempting to mock ClassA as that is what my code is using. The mock creates fine, however when I add an expectation like so:
expect(mockClassA.methodA()).andReturn("string");
I get the following error:
java.lang.IllegalStateException: missing behavior definition for the preceding method call methodA()
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:43)
at org.powermock.api.easymock.internal.invocationcontrol.EasyMockMethodInvocationControl.invoke(EasyMockMethodInvocationControl.java:95)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:104)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:167)
at .ClassC.methodA(ClassC.java)
Any thoughts on what I am missing? I know I haven't included much detail, but I have prepared ClassA for test using the notation, I have also only put the replay in one place to ensure that I am not incorrectly putting mockClassA into the wrong state before setting the expectation.
I did something like this and it works for me, however I dont understand why you need PowerMock here(you can do that without it with EasyMock/Mockito).
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassA.class)
public class ClassATest {
#Test
public void finalMethodString() throws Exception {
ClassA f = PowerMock.createNiceMock(ClassA.class);
EasyMock.expect(f.methodA()).andReturn("haha");
EasyMock.replay(f);
assertEquals("haha1", f.methodA());
}
}
class ClassA extends ClassB{
#Override
String methodA() {
return "1";
}
}
class ClassB extends ClassC{
#Override
String methodA() {
return "b";
}
}
class ClassC {
String methodA() {
return null;
}
}

Resources