Declare parents aspectj - spring

Firstly I try xml configuration:
<aop:aspect>
<aop:declare-parents types-matching="DBOperations.ILearningData+"
implement-interface="DBOperations.ISaveResults"
delegate-ref="saverExtension"/>
</aop:aspect>
and it works good.
Now I try to make aspectj, which should do the same:
public aspect ASaveResults {
public ASaveResults() { }
declare parents : TSaveResults implements ILearningData;
}
where TSaveResults is the same as the bean "saverExtension".
I run my code:
...
#Value("#{learningData}")
protected ILearningData saver;
...
((ISaveResults)saver).saveResults();
and get the error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.proxy.$Proxy12 cannot be cast to DBOperations.ISaveResults
what is the problem with my aspectj?
Also I tried this code unsuccessfully:
public aspect ASaveResults {
public ASaveResults() { }
declare parents : ISaveResults implements ILearningData;
public void saveResults() {
System.out.println("saver aspect");
}
}

What you used there is core aspectj, so if you want to use Spring AOP, but not xml config then this is what you should do (not tested):
#Aspect
public class ASaveResults {
#DeclareParents(value="ISaveResults")
public static ILearningData interf;
public void saveResults() {
System.out.println("saver aspect");
}
}

public aspect ASaveResults {
public ASaveResults() { }
declare parents : LearningData extends TSaveResults;
}
where LearningData and TSaveResults - classes. So now TSaveResults extends LearningData - this was my goal

Related

spring-data-envers -2.0.0.RELEASE

Right now we are using 0.3.0.RELEASE to get the revision data and noticed that the revisions are fetched in ascending order.
the existing code
#EnableJpaRepositories( value = "org.xxx.xxx.xxx.repository", repositoryFactoryBeanClass = RevisionRepositoryFactoryBean.class )
#EnableJpaAuditing( auditorAwareRef = "springSecurityAuditorAware" )
#EnableTransactionManagement
public class DatabaseConfiguration {
.......
}
public class RevisionRepositoryFactoryBean extends EnversRevisionRepositoryFactoryBean {
public RevisionRepositoryFactoryBean() {
setRevisionEntityClass( Revision.class );
}
}
Found that the newer version 2.0.0.RELEASE has functionality to sort based on sort in pageable object. So wanted to use 2.0.0.RELEASE.
the following is the modifications
public class RevisionRepositoryFactoryBean<T extends RevisionRepository<S, ID, N>, S, ID extends Serializable, N extends Number & Comparable<N>> extends EnversRevisionRepositoryFactoryBean<T, S, ID,N> {
public RevisionRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
super(repositoryInterface);
setRevisionEntityClass( Revision.class );
// TODO Auto-generated constructor stub
}
}
but did not work...
compile error in DatabaseConfiguration file
No constructor with 0 arguments defined in class
'org.xxx.xxx.xxx.config.RevisionRepositoryFactoryBean'
Do anyone has an example how to use spring-data-envers -2.0.0.RELEASE in spring boot application.
Thanks
Srini

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.

using spring test context to initialize data

I was wondering if it's possible to initialize test data by implementing the TestExecutionListener interface and use the beforeTestClass and afterTestClass to load/dispose data. The test data will be available in a flat file and I would like the data file location to be as part of the test class annotation
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"classpath:spring/test-dao.xml"})
#TestExecutionListeners(
{
DependencyInjectionTestExecutionListener.class,
InsertTestDataExecutionListener.class
})
#DataSetLocation("classpath:data/test-dao-dataset.xml")
public abstract class AbstractDaoTests {
public List testdata....
}
In the above pseudocode, the InsertTestDataExecutionListener will implement the TestExecutionListener interface and in the beforeClass method, get the dataset location from the annotation. I am trying to find out how I could setup the contents of the property 'testdata' using the TestContext.
public class InsertTestDataExecutionListener implements TestExecutionListener {
public void beforeTestClass(TestContext aContext) {
DataSetLocation dsLocation = aContext.getTestClass().getAnnotation(
DataSetLocation.class
);
//Load the contents of the file using the dataset location.
?? How to set the property of 'testdata' from the Abstract class
}
}
Should I be using reflection to do the work?
As I undestand it is not required to access Spring context during data load (it is just plain file in classpath). So, you may do the work without listeners:
public abstract class AbstractDaoTests {
public List testdata;
public List getTestData() {...}
public abstract String getDataLocation();
public AbstractDaoTests () {
testData = loadDataFromLocation(getTestData());
}
}
public class ConcreteTest extend AbstractDaoTests {
#Override
public String getDataLocation() {return "classpath:data/test-dao-dataset.xml";}
}
Of course you may use annotation instead of abstract method and get it from this.getClass().getAnnotation in constuctor.

NullPointerException in EnumMap when auto generating wadl with Jersey

I am using Tomcat 7, Jaxb2 and Jersey1.11.
I have a class EnumProperty which inherits from an abstract class Property.
#XmlAccessorType(XmlAccessType.FIELD)
public class EnumProperty extends Property<Enum> {
#XmlElement(name = "property_value", nillable = true)
private Enum value;
public EnumProperty() {
setValueType(PropertyValueTypeEnum.ENUM);
}
#Override
public Enum getValue() {
return value;
}
#Override
public void setValue(Enum value) {
this.value = value;
}
}
There are other sub classes for the Property class. In addition, I have another class, Entity, which holds a collection of properties. I have also a resource which returns in one of its sub resources a Collection. When I try to generate my application wadl I receive a NullPointerException. I isolated the problem to the EnumProperty class. Can anyone please help me understand where the problem is?
java.lang.NullPointerException
java.util.EnumMap.<init>(Unknown Source)
com.sun.xml.bind.v2.model.impl.RuntimeEnumLeafInfoImpl.<init>(RuntimeEnumLeafInfoImpl.java:87)
com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createEnumLeafInfo(RuntimeModelBuilder.java:109)
com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createEnumLeafInfo(RuntimeModelBuilder.java:85)
com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:228)
com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:104)
com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:85)
com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:213)
com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:99)
com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:85)
com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:319)
com.sun.xml.bind.v2.model.impl.TypeRefImpl.calcRef(TypeRefImpl.java:96)
com.sun.xml.bind.v2.model.impl.TypeRefImpl.getTarget(TypeRefImpl.java:73)
com.sun.xml.bind.v2.model.impl.RuntimeTypeRefImpl.getTarget(RuntimeTypeRefImpl.java:62)
com.sun.xml.bind.v2.model.impl.RuntimeTypeRefImpl.getTarget(RuntimeTypeRefImpl.java:55)
com.sun.xml.bind.v2.model.impl.ElementPropertyInfoImpl$1.get(ElementPropertyInfoImpl.java:78)
com.sun.xml.bind.v2.model.impl.ElementPropertyInfoImpl$1.get(ElementPropertyInfoImpl.java:81)
java.util.AbstractList$Itr.next(Unknown Source)...

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