Strange GWT serialization exception when overiding method of serialized object - gwt-rpc

I have a GWT serializable class, lets call it Foo.
Foo implements IsSerializable, has primitive and serializable members as well as other transient members and a no-arg constructor.
class Foo implements IsSerializable {
// transient members
// primitive members
public Foo() {}
public void bar() {}
}
Also a Service which uses Foo instance in RPC comunication.
// server code
public interface MyServiceImpl {
public void doStuff(Foo foo);
}
public interface MyServiceAsync {
void doStuff(Foo foo, AsyncCallback<Void> async);
}
How i use this:
private MyServiceAsync myService = GWT.create(MyService.class);
Foo foo = new Foo();
...
AsyncCallback callback = new new AsyncCallback {...};
myService.doStuff(foo, callback);
In the above case the code is running, and the onSuccess() method of callback instance gets executed.
But when I override the bar() method on foo instance like this:
Foo foo = new Foo() {
public void bar() {
//do smthng different
}
};
AsyncCallback callback = new new AsyncCallback {...};
myService.doStuff(foo, callback);
I get the GWT SerializationException.
Please enlighten me, because I really don't understand why.

I think the problem comes from the rpc serialization policy which creates a "white list" of serializable types for the rpc service.
In your case the "Foo" class is in the whitelist but when you override a method, you create an anonymous class that extends Foo but is not in the whitelist, so GWT refuses to serialize it... and I see no way to do what you want without creating an explicit subclass...

Related

How to mock or prepare test methods in case we called private method inside the method?

While writing a testCase for Controller class,The private method that is getServiceContext(). has different object because
one we are passing serviceContext from testclass and other object inside the controller class itself call itself.Due to this Foo object is null. how to resolve this.
public class Controller {
#Refernce
private FooService fooService;
public CustomData getDetails(String id){
Foo foo = fooService.getFoo(id ,**getServiceContext()**);
//getServiceContext() is different object
System.out.println("foo data>>>> "+foo); // **Throwing null pointer exceptions**
CustomData customData = new CustomData();
customData.setStudentName(foo.getName);
customData.setStudentName(foo.getId);
...
...
...
return customData;
}
private ServiceContext getServiceContext() {
ServiceContext serviceContext = new ServiceContext();
serviceContext.setCompanyId(context..);
serviceContext.setUserId(context..);
...
....
retrn serviceContext;
}
}
public class ControllerTest {
#InjectMocks
private Controller controller;
#Mock
private FooService fooService;
private Foo foo;
#BeforeEach
public void setUp() throws PortalException {
foo = mock(Foo.class);
}
#Test
public void getDetailsTest() throws Exception {
ServiceContext **serviceContext** = new ServiceContext();
serviceContext.setCompanyId(context..);
serviceContext.setUserId(context..);
...
....
Mockito.when(fooService.getFoo("testId",serviceContext)).thenReturn(foo);
System.out.println("Service context>>>> "+**serviceContext**); // different serviceContext object
CustomData customData = controller.getDetails("testId");
Assertions.assertThat(ss).isNotNull();
}
}
There are multiple ways to do that.
First, we can mock with anyOf(Type.class), that will actually match object type rather than value.
Mockito
.when(fooService.getFoo(Mockit.eq("testId"), Mockito.any(ServiceContext.class)))
.thenReturn(foo);
this will work as expected and return the desired value.
Additionally, if you want to check with what data serviceContext object is being passed as arg in service method, (as we just checked object type rather than value), We can use ArgumentCaptor for that.
It basically captures argument data which is being passed in the method call.
let's create ArgumentCaptor for service context
#Mock
private FooService fooService;
#Captor
private ArgumentCaptor<ServiceContext> captor;
Now, let's capture the argument during verification.
Mockito.verify(fooService).getFoo(Mockit.eq("testId"), captor.capture());
Assertions.assertEquals("value of x in context", captor.getValue().getX());
Basically here, captor.getValue() returns service context object which is being passed. So, you can verify all data you want to validate in that object.
Alternate, Approach would be Spy which will basically spy on the class under test and you can control the behavior of private methods in test class itself.
To do that, we need to add #Spy annotation along with #InjectMocks on test class.
#Spy
#InjectMocks
private Controller controller;
Now, you can mock the private method and return the expected value.
Mockito.doReturn(serviceContextValue).when(controller).getServiceContext();
and use that object for mocking fooService.
Mockito.verify(fooService).getFoo("testId", serviceContextValue);
But when using Spy, don't forget to write unit test for private method as it's mocked, it's business logic will not be tested by above test cases. that's a reason, it's not recommended way.
I would suggest using ArgumentCaptor approach.

Closure Coercion not working in certain case

I'm calling a Java method from Groovy which expects an instance of a SAM interface as a parameter.
Normally Groovy is happy with passing in a closure in these cases, and will coerce it accordingly HOWEVER in this case, the interface extends another one and overrides the single method.
Note - It still only has one method, but it's been overriden.
In this instance Groovy doesn't automatically coerce the closure and the only way I seem to be able to call it is by using "AS".
I'm publishing an API to help kids to learn code and really don't want them to have to use "AS" because it would complicate things.
Here's some code that shows the issue...
Java
public interface BaseHandler<T> {
public void handle(T test);
}
public interface Handler extends BaseHandler<String> {
public void handle(String test);
}
public class LibraryClass {
public void method(Handler handler) {
handler.handle("WORLD!");
}
}
Groovy
LibraryClass bar = new LibraryClass();
bar.method({ name -> println "HELLO " + name})
Error
Caught: groovy.lang.MissingMethodException: No signature of method: Bar.doIt() is applicable for argument types: (testClosures$_run_closure1) values: [testClosures$_run_closure1#fe63b60]
Any help on how to get around this without using "AS" would be hugely appreciated
Groovy wants to implement the interface by coercion, but doesn't know which interface method it should implement. As there are 2:
the handle(String test) and a second one: handle(String test) (of the baseHandler)
The solution is to remove the handle(String test) from the handler (it adds nothing as the BaseHandler posesses this method already thanks to the generics).
Like this it works correctly:
public interface BaseHandler<T> {
public void handle(T test);
}
public interface Handler extends BaseHandler<String> {
}
public class LibraryClass {
public void method(Handler handler) {
handler.handle("WORLD!");
}
}

How to use PowerMockito to verify super method is called

I am testing a legacy code that use inheritance method. I am trying to mock super-method
to verity if the super-method is being call or not.
#RunWith(PowerMockRunner.class)
public class HumanTest {
#Test
public void test() throws NoSuchMethodException, SecurityException {
// 1. arrange
Human sut = PowerMockito.spy(new Human());
PowerMockito.doNothing().when((SuperHuman) sut).run(); // SuperHuman is the parent class
// 2. action
sut.run();
// 3. assert / verify
}
}
public class Human extends SuperHuman {
#Override
public void run() {
System.out.println("human run");
super.run();
}
}
public class SuperHuman {
public void run() {
System.out.println("superhuman run");
}
}
I was expecting that "human run" will be printed. But the actual result was none printed.
PowerMockito.doNothing().when((SuperHuman) sut).run(); // SuperHuman is the parent class
This won't work in your case since PowerMockito will mock method of Human even if you made cast.
I checked your code example and could say that it is possible to suppress invocation of super class method with:
Method toReplace = PowerMockito.method(SuperHuman.class, "run");
PowerMockito.suppress(toReplace);
But it seems that method replacment feature does not work for methods of super class:
createPartialMock should support mocking overridden methods in super classes.
So this does not work:
PowerMockito.replace(toReplace).with(new InvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Method of superclass has been invoked !");
return null;
}
});
But still you should be able to verify invocation of super method let's say indirectly, by mocking other classes which are invoked in super method only.
For instance check that System.out.println was invoked with "superhuman run" or something like this.

Is private method in spring service implement class thread safe

I got a service in an project using Spring framework.
public class MyServiceImpl implements IMyService {
public MyObject foo(SomeObject obj) {
MyObject myobj = this.mapToMyObject(obj);
myobj.setLastUpdatedDate(new Date());
return myobj;
}
private MyObject mapToMyObject(SomeObject obj){
MyObject myojb = new MyObject();
ConvertUtils.register(new MyNullConvertor(), String.class);
ConvertUtils.register(new StringConvertorForDateType(), Date.class);
BeanUtils.copyProperties(myojb , obj);
ConvertUtils.deregister(Date.class);
return myojb;
}
}
Then I got a class to call foo() in multi-thread;
There goes the problem. In some of the threads, I got error when calling
BeanUtils.copyProperties(myojb , obj);
saying Cannot invoke com.my.MyObject.setStartDate - java.lang.ClassCastException#2da93171
obviously, this is caused by ConvertUtils.deregister(Date.class) which is supposed to be called after BeanUtils.copyProperties(myojb , obj);.
It looks like one of the threads deregistered the Date class out while another thread was just about to call BeanUtils.copyProperties(myojb , obj);.
So My question is how do I make the private method mapToMyObject() thread safe?
Or simply make the BeanUtils thread safe when it's used in a private method.
And will the problem still be there if I keep the code this way but instead I call this foo() method in sevlet? If many sevlets call at the same time, would this be a multi-thread case as well?
Edit: Removed synchronized keyword since it is not neccessary, see comments below.
Instead of using the static methods in the BeanUtils class, use a private BeanUtilsBean instance (http://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/BeanUtilsBean.html). This way, you don't need to register/deregister your converters each time the method is called.
public class MyServiceImpl implements IMyService {
private final BeanUtilsBean beanUtilsBean = createBeanUtilsBean();
private static BeanUtilsBean createBeanUtilsBean() {
ConvertUtilsBean convertUtilsBean = new ConvertUtils();
convertUtilsBean.register(new MyNullConvertor(), String.class);
convertUtilsBean.register(new StringConvertorForDateType(), Date.class);
BeanUtilsBean beanUtilsBean = new BeanUtilsBean(convertUtilsBean);
return beanUtilsBean;
}
public MyObject foo(SomeObject obj) {
MyObject myobj = this.mapToMyObject(obj);
myobj.setLastUpdatedDate(new Date());
return myobj;
}
private MyObject mapToMyObject(SomeObject obj){
MyObject myojb = new MyObject();
beanUtilsBean.copyProperties(myojb , obj);
return myojb;
}
}
add a synchonized block to the sensitive portion of your code or synchronize the method:
http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

Invoking Delegates from a dispatcher

I've been stuck on this all morning, even though it seems like it should be very easy (wondering if I'm missing something fundamental). I have the following code in a class-
public class myClass
{
private Dispatcher m_Dispatcher;
private void myMethod() { ... }
private void invokeTheMethod(object sender, PropertyChangedEventArgs e)
{
m_Dispatcher.Invoke(myMethod); //XYZ
}
}
The dispatcher is attached to the thread that instance of myClass is running on. The invokeTheMethod method is called from another thread, and I'd like to run myMethod on the thread of m_Dispatcher. However, if I try to run this code, I get an exception at XYZ saying "Object reference not an instance of an object". Is this because I haven't declared myMethod in the form of a delegate? - I have tried different ways to declare myMethod as a delegate, but I can't get any of them to compile. Any suggestions are very much appreciated.
Thanks,
Chris
The error you get
Object reference not an instance of an object (NullReferenceException)
refers to the field m_Dispatcher. It is null. That is why you cannot call the Invoke method on it.
Even if there is an instance of Dispatcher "attached to the thread", there is no way for myClass to get hold of that instance.
What you could do is to supply the instance of Dispatcher to myClass when you create an instance of myClass. Something like this:
public class myClass
{
// Here is the 'injection' of the instance in the constructor of this class
public myClass(Dispatcher dispatcher) {
m_Dispatcher = dispatcher;
}
private Dispatcher m_Dispatcher;
private void myMethod() { ... }
private void invokeTheMethod(object sender, PropertyChangedEventArgs e)
{
m_Dispatcher.Invoke(myMethod); //XYZ
}
}
As a side note, you should read up some on coding conventions as your casing is considered wrong by the majority of the C# development community. Here is a good start: http://msdn.microsoft.com/en-us/library/vstudio/w2a9a9s3.aspx

Resources