spring 3 AOP anotated advises - aop

Trying to figure out how to Proxy my beans with AOP advices in annotated way.
I have a simple class
#Service
public class RestSampleDao {
#MonitorTimer
public Collection<User> getUsers(){
....
return users;
}
}
i have created custom annotation for monitoring execution time
#Target({ ElementType.METHOD, ElementType.TYPE })
#Retention(RetentionPolicy.RUNTIME)
public #interface MonitorTimer {
}
and advise to do some fake monitoring
public class MonitorTimerAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable{
try {
long start = System.currentTimeMillis();
Object retVal = invocation.proceed();
long end = System.currentTimeMillis();
long differenceMs = end - start;
System.out.println("\ncall took " + differenceMs + " ms ");
return retVal;
} catch(Throwable t){
System.out.println("\nerror occured");
throw t;
}
}
}
now i can use it if i manually proxy the instance of dao like this
AnnotationMatchingPointcut pc = new AnnotationMatchingPointcut(null, MonitorTimer.class);
Advisor advisor = new DefaultPointcutAdvisor(pc, new MonitorTimerAdvice());
ProxyFactory pf = new ProxyFactory();
pf.setTarget( sampleDao );
pf.addAdvisor(advisor);
RestSampleDao proxy = (RestSampleDao) pf.getProxy();
mv.addObject( proxy.getUsers() );
but how do i set it up in Spring so that my custom annotated methods would get proxied by this interceptor automatically? i would like to inject proxied samepleDao instead of real one. Can that be done without xml configurations?
i think should be possible to just annotate methods i want to intercept and spring DI would proxy what is necessary.
or do i have to use aspectj for that? would prefere simplest solution :- )
thanks a lot for help!

You haven't to use AspectJ, but you can use AspectJ annotations with Spring (see 7.2 #AspectJ support):
#Aspect
public class AroundExample {
#Around("#annotation(...)")
public Object invoke(ProceedingJoinPoint pjp) throws Throwable {
...
}
}

Related

Hazelcast 3.6.1 "There is no suitable de-serializer for type" exception

I am using Hazelcast 3.6.1 to read from a Map. The object class stored in the map is called Schedule.
I have configured a custom serializer on the client side like this.
ClientConfig config = new ClientConfig();
SerializationConfig sc = config.getSerializationConfig();
sc.addSerializerConfig(add(new ScheduleSerializer(), Schedule.class));
...
private SerializerConfig add(Serializer serializer, Class<? extends Serializable> clazz) {
SerializerConfig sc = new SerializerConfig();
sc.setImplementation(serializer).setTypeClass(clazz);
return sc;
}
The map is created like this
private final IMap<String, Schedule> map = client.getMap("schedule");
If I get from the map using schedule id as key, the map returns the correct value e.g.
return map.get("zx81");
If I try to use an SQL predicate e.g.
return new ArrayList<>(map.values(new SqlPredicate("statusActive")));
then I get the following error
Exception in thread "main" com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable de-serializer for type 2. This exception is likely to be caused by differences in the serialization configuration between members or between clients and members.
The custom serializer is using Kryo to serialize (based on this blog http://blog.hazelcast.com/comparing-serialization-methods/)
public class ScheduleSerializer extends CommonSerializer<Schedule> {
#Override
public int getTypeId() {
return 2;
}
#Override
protected Class<Schedule> getClassToSerialize() {
return Schedule.class;
}
}
The CommonSerializer is defined as
public abstract class CommonSerializer<T> implements StreamSerializer<T> {
protected abstract Class<T> getClassToSerialize();
#Override
public void write(ObjectDataOutput objectDataOutput, T object) {
Output output = new Output((OutputStream) objectDataOutput);
Kryo kryo = KryoInstances.get();
kryo.writeObject(output, object);
output.flush(); // do not close!
KryoInstances.release(kryo);
}
#Override
public T read(ObjectDataInput objectDataInput) {
Input input = new Input((InputStream) objectDataInput);
Kryo kryo = KryoInstances.get();
T result = kryo.readObject(input, getClassToSerialize());
input.close();
KryoInstances.release(kryo);
return result;
}
#Override
public void destroy() {
// empty
}
}
Do I need to do any configuration on the server side? I thought that the client config would be enough.
I am using Hazelcast client 3.6.1 and have one node/member running.
Queries require the nodes to know about the classes as the bytestream has to be deserialized to access the attributes and query them. This means that when you want to query on objects you have to deploy the model classes (and serializers) on the server side as well.
Whereas when you use key-based access we do not need to look into the values (neither into the keys as we compare the byte-arrays of the key) and just send the result. That way neither model classes nor serializers have to be available on the Hazelcast nodes.
I hope that makes sense.

Spring JDBC and Java 8 - JDBCTemplate: retrieving SQL statement and parameters for debugging

I am using Spring JDBC and some nice Java 8 lambda-syntax to execute queries with the JDBCTemplate.
The reason for choosing Springs JDBCTemplate, is the implicit resource-handling that Spring-jdbc offers (I do NOT want a ORM framework for my simple usecase's).
My problem is that I want to debug the whole SQL statements with their parameters. Spring prints the SQL by default but not the parameters. Therefor I have subclassed the JDBCTemplate and overridden a query-method.
An example usage of the JDBCTemplate:
public List<Product> getProductsByModel(String modelName) {
List<Product> productList = jdbcTemplate.query(
"select * from product p, productmodel m " +
"where p.modelId = m.id " +
"and m.name = ?",
(rs, rowNum) -> new Product(
rs.getInt("id"),
rs.getString("stc_number"),
rs.getString("version"),
getModelById(rs.getInt("modelId")), // method not shown
rs.getString("displayName"),
rs.getString("imageUrl")
),
modelName);
return productList;
}
To get hold of the parameters I have, as mentioned, overridden the JDBCTemplate class. By doing a cast and using reflection I get the Object[] field with the parameters from an instance of ArgumentPreparedStatementSetter.
I suspect this implementation could potentially be dangerous, as the actual implementation of the PreparedStatementSetter may not always be ArgumentPreparedStatementSetter (Yes I should do an instanceOf check). Also, the reflection code may not be as elegant, but that is besides the point now though :).
Here's my custom implementation:
public class CustomJdbcTemplate extends JdbcTemplate {
private static final Logger log = LoggerFactory.getLogger(CustomJdbcTemplate.class);
public CustomJdbcTemplate(DataSource dataSource) {
super(dataSource);
}
public <T> T query(PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)
throws DataAccessException {
if(log.isDebugEnabled()) {
ArgumentPreparedStatementSetter aps = (ArgumentPreparedStatementSetter) pss;
try {
Field args = aps.getClass().getDeclaredField("args");
args.setAccessible(true);
Object[] parameters = (Object[]) args.get(aps);
log.debug("Parameters for SQL query: " + Arrays.toString(parameters));
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new GenericException(e.toString(), e);
}
}
return super.query(psc, pss, rse);
}
}
So, when I execute the log.debug(...) statement I would also like to have the original SQL query logged (same line). Has anyone done something similar or are there any better suggestions as to how this can be achieved?
I do quite a few queries using this CustomJDBCTemplate and all my tests run, so I think it may be an acceptable solution of for most debug purposes.
Kind regards,
Thomas
I found a way to get the SQL-statement, so I will answer my own question :)
The PreparedStatementCreator has the following implementation:
private static class SimplePreparedStatementCreator implements PreparedStatementCreator, SqlProvider
So the SqlProvider has a getSql() method which does exactly what I need.
Posting the "improved" CustomJdbcTemplate class if anyone ever should need to do the same :)
public class CustomJdbcTemplate extends JdbcTemplate {
private static final Logger log = LoggerFactory.getLogger(CustomJdbcTemplate.class);
public CustomJdbcTemplate(DataSource dataSource) {
super(dataSource);
}
public <T> T query(PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)
throws DataAccessException {
if(log.isDebugEnabled()) {
if(pss instanceof ArgumentPreparedStatementSetter) {
ArgumentPreparedStatementSetter aps = (ArgumentPreparedStatementSetter) pss;
try {
Field args = aps.getClass().getDeclaredField("args");
args.setAccessible(true);
Object[] parameters = (Object[]) args.get(aps);
log.debug("SQL query: [{}]\tParams: {} ", getSql(psc), Arrays.toString(parameters));
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new GenericException(e.toString(), e);
}
}
}
return super.query(psc, pss, rse);
}
private static String getSql(Object sqlProvider) { // this code is also found in the JDBCTemplate class
if (sqlProvider instanceof SqlProvider) {
return ((SqlProvider) sqlProvider).getSql();
}
else {
return null;
}
}
}

Hibernate3 --> Hibernate 4 and issues (Lazy...)

I'm trying to update the libraries of my project (from Hibernate 3.2.1 GA to Hibernate 4.2.8)
This (complex) application use LAZY loading and get the object later only when we need it.
-->it seems to work differently now because I get some org.hibernate.LazyInitializationException: could not initialize proxy - no Session
#Entity
#Table(name = "CLIENTS")
public class Clients {
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "INFOIDT", insertable = true, updatable = false)
private Information info;
//...
}
and when I need to know more about the product before using it :
cli.getInfo();
Note that in my persistence.xml I also have the property
hibernate.cache.provider_class set to org.hibernate.cache.EhCacheProvider for a second level cache.
QUESTION : what is the simple way to migrate my existing code with Hibernate4?
(the class given for example above is a fake example to illustrate the many cases using the LAZY loading)
Thank you.
As requested, see my DAO below :
public class MyAppJpaDAO extends GenericJpaDAO implements IMyAppDAO {
protected static Log log = LogFactory.getLog(MyAppJpaDAO.class);
// Entity Manager of the project
#PersistenceContext(unitName = "MyApp.hibernate")
private EntityManager em;
public News readLastNews() {
StringBuffer sql = new StringBuffer("");
sql.append(" select object(n) ");
sql.append(" from News n ");
sql.append(" Where n.flagLastStatus = 'V' ");
sql.append(" order by n.pk.date desc ");
Query aQuery = em.createQuery(sql.toString());
List<News> res = (List<News>) aQuery.getResultList();
if (res != null && res.size() != 0) {
return res.get(0);
}
return null;
}
//...
}
/////////////
public class GenericJpaDAO implements IGenericDAO {
protected static Log log = LogFactory.getLog(GenericJpaDAO.class);
#PersistenceContext(unitName = "MyApp.hibernate")
EntityManager em;
public Object getReference(Class _class, Object _object) {
return em.getReference(_class, _object);
}
public void createObject(Object object) {
try {
em.persist(object);
} catch (LazyInitializationException lie) {
em.merge(em.merge(object));
}
}
public void deleteObject(Object object) {
try {
em.remove(object);
} catch (Exception e) {
em.remove(em.merge(object));
}
}
public void updateObject(Object object) {
em.merge(em.merge(object));
}
//...
}
If you want to use LazyLoading, you need to have the session opened and connected at the time when you calls .getInfo(). org.hibernate.LazyInitializationException occures if you tries to get an entity but the session is disconnected or closed.
I think you have problems with session handling. There is nothing to do with the entities.
If the SessionFactory is configured in a Spring context file, we can use the OpenSessionInViewFilter to keep the session open.
<filter>
<filter-name>Hibernate Session In View Filter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Hibernate Session In View Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Unfortunately, my application is not configured like this...
Interesting...but still not helping
http://www.javacodegeeks.com/2012/07/four-solutions-to-lazyinitializationexc_05.html
But I find something :
1)Hibernate 3.2.1 GA and Spring 2.0
I used to put a Person having a LAZY bag in a Group and when I wanted to get some pencil from the bag of any person of the group, I was able to get it.
2)Hibernate 4.2.8 et Spring 3.2.5.
If I don't explicitely ask to know the content of the bag just after getting the Person and before putting it into the group, I will have the lazy exception.
If someone could explain me why...

Rhino.Mocks how to test abstract class method calls

I'm trying to test if the method I want to test calls some external (mock) object properly.
Here is the sample code:
using System;
using Rhino.Mocks;
using NUnit.Framework;
namespace RhinoTests
{
public abstract class BaseWorker
{
public abstract int DoWork(string data);
}
public class MyClass
{
private BaseWorker worker;
public BaseWorker Worker
{
get { return this.worker; }
}
public MyClass(BaseWorker worker)
{
this.worker = worker;
}
public int MethodToTest(string data)
{
return this.Worker.DoWork(data);
}
}
[TestFixture]
public class RhinoTest
{
[Test]
public void TestMyMethod()
{
BaseWorker mock = MockRepository.GenerateMock<BaseWorker>();
MyClass myClass = new MyClass(mock);
string testData = "SomeData";
int expResponse = 10;
//I want to verify, that the method forwards the input to the worker
//and returns the result of the call
Expect.Call(mock.DoWork(testData)).Return(expResponse);
mock.GetMockRepository().ReplayAll();
int realResp = myClass.MethodToTest(testData);
Assert.AreEqual(expResponse, realResp);
}
}
}
When I run this test, I get:
TestCase 'RhinoTests.RhinoTest.TestMyMethod'
failed: System.InvalidOperationException : Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).
at Rhino.Mocks.LastCall.GetOptions[T]()
at Rhino.Mocks.Expect.Call[T](T ignored)
RhinoTest.cs(48,0): at RhinoTests.RhinoTest.TestMyMethod()
The exception is thrown on the Expect.Call line, before any invocation is made.
How do I approach this - i.e. how to check if the method under test properly forwards the call?
This is .Net 2.0 project (I can no change this for now), so no "x =>" syntax :(
I have to admit, I'm not entirely sure what's going on here, but using Rhino.Mocks 3.6 and the newer syntax, it works fine for me:
[Test]
public void TestMyMethod()
{
MockRepository mocks = new MockRepository();
BaseWorker mock = mocks.StrictMock<BaseWorker>();
MyClass myClass = new MyClass(mock);
string testData = "SomeData";
int expResponse = 10;
using (mocks.Record())
{
//I want to verify, that the method forwards the input to the worker
//and returns the result of the call
Expect.Call(mock.DoWork(testData)).Return(expResponse);
}
using (mocks.Playback())
{
int realResp = myClass.MethodToTest(testData);
Assert.AreEqual(expResponse, realResp);
}
}
It doesn't have anything to do with the Rhino.Mocks version. With the old syntax, I get the same error as you're getting. I didn't spot any obvious errors in your code, but then again, I'm used to this using syntax.
Edit: removed the var keyword, since you're using .NET 2.0.

How to mock method call from other class in Rhino Mock AAA?

I have the following code(simplified).
public class OrderProcessor
{
public virtual string PlaceOrder(string test)
{
OrderParser orderParser = new OrderParser();
string tester = orderParser.ParseOrder(test);
return tester + " here" ;
}
}
public class OrderParser
{
public virtual string ParseOrder(string test)
{
if (!string.IsNullOrEmpty(test.Trim()))
{
if (test == "Test1")
return "Test1";
else
{
return "Hello";
}
}
else
return null;
}
}
My test is as follows -
public class OrderTest
{
public void TestParser()
{
// Arrange
var client = MockRepository.GenerateMock<OrderProcessor>();
var spec = MockRepository.GenerateStub<OrderParser>();
spec.Stub(x => x.ParseOrder("test")).IgnoreArguments().Return("Test1");
//How to pass spec to client so that it uses the same.
}
}
Now how do I test client so that it uses the mocked method from OrderParser.
I can mock the OrderParser but how do I pass that to the orderProcessor mocked class?
Please do let me know.
Thanks in advance.
I'm a little confused by your test since you are not really testing anything except that RhinoMocks works. You create two mocks and then do some assertions on them. You haven't even tested your real classes.
You need to do some dependency injection if you really want to get a good unit test. You can quickly refactor your code to use interfaces and dependency injection to make your test valid.
Start by extracting an interface from your OrderParser class:
public interface IOrderParser
{
String ParseOrder(String value);
}
Now make sure your OrderParser class implements that interface:
public class OrderParser: IOrderParser{ ... }
You can now refactor your OrderProcessor class to take in an instance of an IOrderParser object through its constructor. In this way you "inject" the dependency into the class.
public class OrderProcessor
{
IOrderParser _orderParser;
public OrderProcessor(IOrderParser orderParser)
{
_orderParser = orderParser;
}
public virtual string PlaceOrder(string val)
{
string tester = _orderParser.ParseOrder(val);
return tester + " here" ;
}
}
In your test you only want to mock out the dependency and not the SUT (Subject Under Test). Your test would look something like this:
public class OrderTest
{
public void TestParser()
{
// Arrange
var spec = MockRepository.GenerateMock<IOrderParser>();
var client = new OrderProcessor(spec);
spec.Stub(x => x.ParseOrder("test")).IgnoreArguments().Return("Test1");
//Act
var s = client.PlaceOrder("Blah");
//Assert
Assert.AreEqual("Test1 Here", s);
}
}
It is difficult for me to gauge what you are trying to do with your classes, but you should be able to get the idea from this. A few axioms to follow:
Use interfaces and composition over inheritance
Use dependency injection for external dependencies (inversion of control)
Test a single unit, and mock its dependencies
Only mock one level of dependencies. If you are testing class X which depends on Y which depends on Z, you should only be mocking Y and never Z.
Always test behavior and never implementation details
You seem to be on the right track, but need a little guidance. I would suggest reading material that Martin Fowler, and Bob Martin have to get up to speed.