You may know that testing with GWTTestCase are very slow. And there are many posts about testing GWT applications without using GWTTestCase.
However, it is still hard to test our RPC remote services. That is the reason I decided to develop SyncProxy which can run directly from pure Java (non JSNI) code.
Simple Test case
For example, we have an helloApp application and we want to test our GreetingService
@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
String greetServer(String name);
}
Assume the server side of application is running (whether in DevMode or deployed to an web server) and the servlet URL is configured at http://localhost/helloApp/greet
The test case
public class GreetingServiceTest extends TestCase{
private static GreetingService rpcService =
SyncProxy.newProxyInstance(GreetingService.class,
"http://localhost/helloApp", "greet");
public void testGreeting() {
String result = rpcService.greetServer("SyncProxy");
assertTrue((result != null) && (result.startsWith("Hello, SyncProxy")))
}
}
Explanation
SyncProxy.newProxyInstance() method requires a service interface class, a base URL and a relative servlet path.
SyncProxy will search for RPC policy files (*.gwt.rpc files) to determine appropriate policy name for the service interface. Thus, we copy gwt.rpc files from war/helloApp directory to our test case classpath.
SyncProxy.newProxyInstance() will return a new proxy instance which implements our GreetingService interface.
Simulating Async
By design SyncProxy is synchronous, e.g it invoke the remote service and wait for the result. However, our GWT logic code invokes the remote service asynchronously. SyncProxy can simulate the ‘Async’ mode too.
GreetingServiceAsync rpcServiceAsync =
SyncProxy.newProxyInstance(GreetingServiceAsync.class,
"http://localhost/helloApp", "greet");
The code is almost the same as section above, except we use the Async version of the remote service interface.
rpcService.greetServer("SyncProxy", new AsyncCallback(){
public void onFailure(Throwable caught) {
...
}
public void onSuccess(String result) {
...
}
});
Download SyncProxy
Get SyncProxy (with source code) at http://code.google.com/p/gwt-syncproxy/
SyncProxy includes test suite (see the Java source file com.gdevelop.gwt.syncrpc.test.RPCSyncSuite) to test against the standard GTW RPC test.
Updated on 2010/03/13: New post Invoke GWT RPC services deployed on Google App Engine describes using SyncProxy with GWT RPC deployed on Google AppEngine.
Hi, I downloaded syncproxy and the jar file appears to be corrupted.
Hi Ron,
Thanks for your feedback. I sent the SyncProxy source code to you. Please check your mail box.
And please tell us what’s wrong with the jar file? Your information is useful for us to prevent the problem for other readers
Will this only test your code locally?
I am trying to built a test suite which I can run monthly on my deployed app. This suite should help me find out if there are any issues. Could this help?
Thanks.
Hi Ed,
Of course, SyncProxy can be used to test the deployed app.
For example, testing the deployed helloApp is as below:
// Create new proxy instance for the helloApp deployed on http://www.example.com
GreetingService rpcService =
SyncProxy.newProxyInstance(GreetingService.class,
“http://www.example.com/helloApp”, “greet”);
Hope this help.
Awesome! Thanks. I’ll try this today!
One more thing. Sorry to keep bothering. Will this work with http sessions?
Hi Ed,
Thanks for your questions. It suggests me a new feature of SyncProxy.
I just released a new version of GWT SyncProxy which supports cookies and therefore supports http sessions.
Checkout the SyncProxy 0.1.1 at the download page.
Please note, the source code is included in the jar file, you can modify it to meet your requirements.
Cheers.
Hi,
I just tried to use this lib and suddenly got exception
An unexpected error has been detected by Java Runtime Environment:
#
# Internal Error (exceptions.cpp:367), pid=2284, tid=3460
# Error: ExceptionMark destructor expects no pending exceptions
#
# Java VM: Java HotSpot(TM) Client VM (10.0-b23 mixed mode, sharing windows-x86)
# An error report file with more information is saved as:
# D:\Java\workspace\Event\hs_err_pid2284.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
Do you have any idea what is a cause ?
Can you please clarify the error is on the server side or the client one?
Well, I’ve just replaced JRE version and it works fine. For now I am using version 6
Hi Trung –
I’m using version 0.1.2 and it works fine when my GWT RPC method completes successfully on the server. However, in some cases the GWT RPC method on the server will throw a SessionTimeoutException – this is a checked exception that I have defined in my code. I would expect that this exception get serialized out to the “client” and thrown in my client (really JUnit test case) code. However, instead I get a serialization exception:
com.google.gwt.user.client.rpc.InvocationException: Exception while invoking the remote service com.aravo.network.client.userprofile.UserProfileService.getPerson
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:173)
at $Proxy0.getPerson(Unknown Source)
at com.aravo.network.client.JunitTest.testGetPerson(JunitTest.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: com.google.gwt.user.client.rpc.InvocationException: IOException
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:154)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:159)
… 21 more
Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:7001/network/network/userprofileservice
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:128)
… 22 more
Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:7001/network/network/userprofileservice
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(Unknown Source)
at com.gdevelop.gwt.syncrpc.CookieManager.storeCookies(CookieManager.java:73)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:126)
… 22 more
Is this expected? Or do you expect that SyncProxy should correctly deal with the exceptions as well? If you could confirm whether this works for you, then I can do some more debugging on my end to try to figure out what is going on.
Thanks,
Constantin
Sorry, the stack trace I posted in my previous comment was not the correct one. Here’s the correct one:
com.google.gwt.user.client.rpc.InvocationException: Exception while invoking the remote service com.aravo.network.client.userprofile.UserProfileService.getPerson
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:173)
at $Proxy0.getPerson(Unknown Source)
at com.aravo.network.client.JunitTest.testGetPerson(JunitTest.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: com.google.gwt.user.client.rpc.InvocationException: Error while performing serialization
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:156)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:159)
… 21 more
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type ‘com.aravo.network.shared.exception.SessionTimeoutException’ was not included in the set of types which can be deserialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be deserialized.
at com.google.gwt.user.server.rpc.impl.StandardSerializationPolicy.validateDeserialize(StandardSerializationPolicy.java:158)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.deserialize(SyncClientSerializationStreamReader.java:364)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:61)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:148)
… 22 more
Hi Constantin,
I fixed the checked exception issue in version 0.1.3.
Download version 0.1.3 at http://code.google.com/p/gwt-syncproxy/downloads/list
Please note, remember to copy *.gwt.rpc to your client classpath.
Try 0.1.3 and post the result here.
Thanks
Trung – Your fix works, thank you very much. However, can you check one other thing for me if you have a chance, namely, whether or not Integer (not int, but Integer) parameters are being correctly serialized in and out? When I try to call an RPC method that takes an Integer parameter, I get the following on the server:
java.lang.ArrayIndexOutOfBoundsException: 1110
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.getString(ServerSerializationStreamReader.java:565)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:55)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader$ValueReader$8.readValue(ServerSerializationStreamReader.java:137)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeValue(ServerSerializationStreamReader.java:384)
at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:296)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:186)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:224)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3498)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(Unknown Source)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
Specifically, the method I am calling takes parameters (Integer,String,String).
I’ve also noticed that when a method returns an Integer object, I don’t seem to get the right value on the client, which is why I am suspecting that there is some problem with serialization of Integers.
Thanks,
Constantin
Hi Constantin,
It seem there is a little bit change in gwt-2.0.3 for serialization for Integer, Long, ect. I will look at it again and revert to you.
Cheers,
Hi, Trung,
I never got success to make a GWT-RPC call by using of SyncProxy.
I don’t know why, could you help me ?
I got the similar problem as Constantin,
I downloaded version 0.1.3, I still got the same problem.
1) Because I have to use https, I made some changes in your code.
in RemoteServiceSyncProxy.java
replaced your code
URL url = new URL(remoteServiceURL);
connection = (HttpURLConnection) url.openConnection();
with
String httpsURL = “https://192.168.2.25:48010″;
URL myurl = new URL(httpsURL);
m_TheHttpsURLConnection = (HttpsURLConnection)myurl.openConnection();
m_TheHttpsURLConnection.setSSLSocketFactory(factory);
I can (https)connect to my server, there is the html response, but
I got the following exceptions :
tmp_debug : doInvoke : requestData : 5|0|4|https://192.168.2.25:48010/#activate|33B97F40B97F77CA20CB4FF41424DAAF|com.testrpc.msm.interfaces.IMSMService|getRandom|1|2|3|4|0|
fsep : \
cacertsFile : MSMTechCert.jks
created keystore
read ca cert. MSMTechCert.jks
ks load. success
Warning: URL Host: 192.168.2.25 vs. 192.168.2.25
SSL sessID length = 16
tmp_debug : doInvoke : statusCode : 200
tmp_debug : doInvoke : HttpURLConnection.HTTP_OK : 200
Exception in thread “main” com.google.gwt.user.client.rpc.InvocationException: E
xception while invoking the remote service com.testrpc.msm.interfaces.IMSMService.
getRandom
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:180)
at $Proxy0.getRandom(Unknown Source)
at callgwtcpc.main(callgwtcpc.java:28)
Caused by: com.google.gwt.user.client.rpc.InvocationException: Unknown response
<!– –>
…
at RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:177)
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:159)
… 2 more
2) Since I do not see “//OK” in the above html output from server,
I’ve changed the return value to “true” in “static boolean isReturnValue(String encodedResponse)”,
I got the following exceptions :
C:\tmp>java callgwtcpc
main
tmp_debug : doInvoke : remoteServiceURL : https://192.168.2.25:48010/#activat
eMSMService
tmp_debug : doInvoke : requestData : 5|0|4|https://192.168.2.25:48010/#activa
te|33B97F40B97F77CA20CB4FF41424DAAF|com.testrpc.msm.interfaces.IMSMService|getRand
om|1|2|3|4|0|
fsep : \
cacertsFile : MSMTechCert.jks
created keystore
read ca cert. MSMTechCert.jks
ks load. success
Warning: URL Host: 192.168.2.25 vs. 192.168.2.25
SSL sessID length = 16
tmp_debug : doInvoke : statusCode : 200
tmp_debug : doInvoke : HttpURLConnection.HTTP_OK : 200
Exception in thread “main” com.google.gwt.user.client.rpc.InvocationException: E
xception while invoking the remote service com.testrpc.msm.interfaces.IMSMService.
getRandom
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:180)
at $Proxy0.getRandom(Unknown Source)
at callgwtcpc.main(callgwtcpc.java:28)
Caused by: java.lang.NumberFormatException: For input string: ”
”);
}
”
at java.lang.NumberFormatException.forInputString(NumberFormatException.
java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)
at SyncClientSerializationStreamReader.readInt(SyncClientSerializationSt
reamReader.java:439)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader
.prepareToRead(AbstractSerializationStreamReader.java:38)
at SyncClientSerializationStreamReader.prepareToRead(SyncClientSerializa
tionStreamReader.java:340)
at RemoteServiceSyncProxy.createStreamReader(RemoteServiceSyncProxy.java
:109)
at RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:171)
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:159)
… 2 more
From the log: tmp_debug : doInvoke : requestData : 5|0|4|https://192.168.2.25:48010/#activate|33B97F40B97F77CA20CB4FF41424DAAF|com.testrpc.msm.interfaces.IMSMService|getRandom|1|2|3|4|0|
Your baseURL (https://192.168.2.25:48010/#activate) seem not correct. The baseURL should be https://192.168.2.25:48010/yourAppName.
Ensure the baseURL and remoteServiceRelativePath are set accordingly to your servlet-mapping configuration.
Hi man:
Your SyncProxy seems to be awesome.
However, when I tried to run the code, my test runner cannot find com.google.gdata.client.GoogleAuthTokenFactory.
Where can I find a jar for this class?
Hi Trung:
SyncProxy appears to be cool. However, when I tried to execute the tests, I got this error:
java.lang.ClassNotFoundException: com.google.gdata.client.GoogleAuthTokenFactory
Where can I locate for this class (com.google.gdata.client.GoogleAuthTokenFactory)?
Thanks.
Hi Phuong,
Download gdata-java-client from http://code.google.com/p/gdata-java-client/downloads/list, and put gdata-core.jar into your client classpath.
Hope this help.
Hi Trung:
I got problem with serialization policy using SyncProxy.
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type ‘xxx.Subject’ was not assignable to ‘com.google.gwt.user.client.rpc.IsSerializable’ and did not have a custom field serializer.For security purposes, this type will not be serialized.: instance = @Subject{English}
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:610)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:129)
at com.google.gwt.user.client.rpc.core.java.util.Collection_CustomFieldSerializerBase.serialize(Collection_CustomFieldSerializerBase.java:43)
at com.google.gwt.user.client.rpc.core.java.util.ArrayList_CustomFieldSerializer.serialize(ArrayList_CustomFieldSerializer.java:36)
Funny thing is that I don’t encounter such exception using normal GWT generated Js code
I’m using GWT 2.0.3 / GAE 1.3.1 (running on localhost)
I was trying to connect to /services/subject and call a method named getAll to get an ArrayList of xxx.Subject
This is the request header that I got by inspecting in Firebug:
Host 127.0.0.1:8888
User-Agent Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
Connection keep-alive
Content-Type text/x-gwt-rpc; charset=utf-8
X-GWT-Permutation E868F76DE0B64296CC01E9813C60135F
X-GWT-Module-Base http://127.0.0.1:8888/adminSubjects/
Referer http://127.0.0.1:8888/adminSubjects/E868F76DE0B64296CC01E9813C60135F.cache.html
Content-Length 139
I wonder if SyncProxy missed some of these headers that cause the problem?
Thanks.
Hi Phuong,
Ensure *.gwt.rpc is in client classpath.
SyncProxy will search for *.gwt.rpc to determine appropriate policy name for the service interface. If not found, the policy name will be null and cause server code unable to serialize/deserialize your classes.
Hope this help.
Hi Trung,
Followed your advice, changed baseURL and confirmed that
remoteServiceRelativePath are set accordingly to your
servlet-mapping configuration.
Here is the servlet-mapping configuration :
@RemoteServiceRelativePath(“MSMService”)
public interface IMSMService extends RemoteService
{
…
}
But still no success, the error still is in
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:449)
I saw your another post saying
“It seem there is a little bit change in gwt-2.0.3 for serialization for Integer, Long, ect. I will look at it again and revert to you.”
probably I have to wait your new version of SyncProxy.
Here is output after chanaged baseURL :
tmp_debug : doInvoke : remoteServiceURL : https://192.168.2.25:48010/MSMServic
e
tmp_debug : doInvoke : requestData : 5|0|4|https://192.168.2.25:48010/MSMServi
ce|33B97F40B97F77CA20CB4FF41424DAAF|com.testrpc.msm.interfaces.IMSMService|getRand
om|1|2|3|4|0|
fsep : \
cacertsFile : MSMTechCert.jks
created keystore
read ca cert. MSMTechCert.jks
ks load. success
SSL sessID length = 16
tmp_debug : doInvoke : statusCode : 200
tmp_debug : doInvoke : HttpURLConnection.HTTP_OK : 200
tmp_debug : doInvoke : encodedResponse :
<!– –>
…
Exception in thread “main” com.google.gwt.user.client.rpc.InvocationException: E
xception while invoking the remote service com.testrpc.msm.interfaces.IMSMService.
getRandom
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:190)
at $Proxy0.getRandom(Unknown Source)
at callgwtcpc.main(callgwtcpc.java:30)
Caused by: java.lang.NumberFormatException: For input string: ”
”);
}
”
at java.lang.NumberFormatException.forInputString(NumberFormatException.
java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)
at SyncClientSerializationStreamReader.readInt(SyncClientSerializationSt
reamReader.java:439)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader
.prepareToRead(AbstractSerializationStreamReader.java:38)
at SyncClientSerializationStreamReader.prepareToRead(SyncClientSerializa
tionStreamReader.java:340)
at RemoteServiceSyncProxy.createStreamReader(RemoteServiceSyncProxy.java
:115)
at RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:183)
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:169)
… 2 more
Hi Trung:
Thanks for the guide. I’m using Sync Proxy now. It’s awesome.
One notice is that SyncProxy cannot work with JDO persistent object in someway, due to a mysterious information included into the JDO object. Using PersistenceCapable(detached=”true”) will remove this information and get SyncProxy work fine with your JDO object.
Best,
Phuong.
By the way, have you figured out what went wrong with Long serialization?
Hi,
Version 0.1.4 fix serialization/deserialization for Double, Float, Long, Integer, Short, Byte, Character and Boolean classes.
Hope this help
Hi Trung:
I’m getting some more problem.
For example, I have a Service like that:
SubjectService{
Subject load(Integer id);
}
SubjectServiceAsync{
void load(Integer id, AsyncCallback callback);
}
service=(SubjectService) SyncProxy.newProxyInstance(SubjectService.class…)
Then service.load(18) would render server to throw this funny exception:
java.lang.ArrayIndexOutOfBoundsException: 18
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.getString(ServerSerializationStreamReader.java:583)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:55)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader$ValueReader$8.readValue(ServerSerializationStreamReader.java:137)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeValue(ServerSerializationStreamReader.java:384)
at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:296)
I hope you can have time to investigate the problem soon.
Best,
Phuong
This looks like a great library to do tests for RPC. Is there any way to make it work with an application that is secured using Spring Security ?
Thanks
Hi belai,
SyncProxy provides a GWT RPC communication channel from pure Java client. You can use GWT RemoteServiceServlet + Spring Security on the server side (I haven’t tried it yet).
I posted a couple issues to the code.google site, however I think one of them may be related to this question:
Does syncproxy support deRPC, or plan to?
Hi dhartford,
Per my understanding, deRPC uses payloads which can be passed directly to the JavaScript eval() function. Because SyncProxy is a pure Java (e.g no JSNI, no JavaScript) client, thus I think SyncProxy will not use deRPC payload.
Hi, Trung,
Since our server side uses gwt 1.7.0, so I tried to use
gwt 1.7.0 in the client side, but I got the compiler errors below. How do I solve this compiling problem ?
I do not have problems to compile SyncProxy with gwt 2.0.0/2.0.3.
C:\gwt_rpc>javac callgwtcpc.java
.\SyncClientSerializationStreamReader.java:25: com.google.gwt.user.server.rpc.im
pl.SerializabilityUtil is not public in com.google.gwt.user.server.rpc.impl; can
not be accessed from outside package
import com.google.gwt.user.server.rpc.impl.SerializabilityUtil;
^
.\SyncClientSerializationStreamWriter.java:26: com.google.gwt.user.server.rpc.im
pl.SerializabilityUtil is not public in com.google.gwt.user.server.rpc.impl; can
not be accessed from outside package
import com.google.gwt.user.server.rpc.impl.SerializabilityUtil;
^
.\SyncClientSerializationStreamReader.java:353: cannot find symbol
symbol : variable SerializabilityUtil
location: class SyncClientSerializationStreamReader
SerializedInstanceReference serializedInstRef = SerializabilityUtil.decodeSe
rializedInstanceReference(typeSignature);
^
.\SyncClientSerializationStreamReader.java:366: cannot find symbol
symbol : variable SerializabilityUtil
location: class SyncClientSerializationStreamReader
Class customSerializer = SerializabilityUtil.hasCustomFieldSerializer(i
nstanceClass);
^
.\SyncClientSerializationStreamReader.java:573: cannot find symbol
symbol : variable SerializabilityUtil
location: class SyncClientSerializationStreamReader
Field[] serializableFields = SerializabilityUtil.applyFieldSerializationPoli
cy(instanceClass);
^
.\SyncClientSerializationStreamReader.java:593: cannot find symbol
symbol : variable SerializabilityUtil
location: class SyncClientSerializationStreamReader
deserializeImpl(SerializabilityUtil.hasCustomFieldSerializer(superClass),
^
.\SyncClientSerializationStreamWriter.java:334: cannot find symbol
symbol : variable SerializabilityUtil
location: class SyncClientSerializationStreamWriter
String serializationSignature = SerializabilityUtil.getSerializationSignatur
e(clazz, serializationPolicy);
^
.\SyncClientSerializationStreamWriter.java:401: cannot find symbol
symbol : variable SerializabilityUtil
location: class SyncClientSerializationStreamWriter
Class customSerializer = SerializabilityUtil.hasCustomFieldSerializer(ins
tanceClass);
^
.\SyncClientSerializationStreamWriter.java:470: cannot find symbol
symbol : variable SerializabilityUtil
location: class SyncClientSerializationStreamWriter
Field[] serializableFields = SerializabilityUtil.applyFieldSerializationPoli
cy(instanceClass);
^
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
9 errors
Hi Trung,
I’m using version 0.1.3 and I get this exception:
No source code is available for type com.gdevelop.gwt.syncrpc.SyncProxy; did you forget to inherit a required module?
Can you help me?
Thanks.
SyncProxy is for pure Java client and will not be compiled to Javascript.
Ensure to not call SyncProxy from your GWT client code.
Thanks for the reply Trung. But it is still not clear to me how you will log in. The only security-enabled call I see is for AppEngine. Will be too much trouble for you to put a simple example on how to test services secured using HTTP BASIC authentication like you did for the AppEngine.
Trung – Just wanted to say that 0.1.4 fixes the problems I was having the Integer serialization. Thanks a lot! – Constantin
Hi,Trung,
I tried your 0.1.4, still no success.
Could you help me to find out why ?
I’ve made two changes in your code :
1) Because I have to use https, I made some changes in your code.
in RemoteServiceSyncProxy.java
replaced your code
URL url = new URL(remoteServiceURL);
connection = (HttpURLConnection) url.openConnection();
with
String httpsURL = “https://192.168.2.25:48010″;
URL myurl = new URL(httpsURL);
m_TheHttpsURLConnection = (HttpsURLConnection)myurl.openConnection();
m_TheHttpsURLConnection.setSSLSocketFactory(factory);
2) Since I do not see “//OK” in the above html output from server,
I’ve changed the return value to “true” in “static boolean isReturnValue(String encodedResponse)”,
Here is the output of execution :
C:\gwt_rpc>java callgwtcpc
main
fsep : \
cacertsFile : MSMTechCert.jks
created keystore
read ca cert. MSMTechCert.jks
ks load. success
requestData = 5|0|4|https://192.168.2.25:48010/MSMService|33B97F40B97F77CA20CB
4FF41424DAAF|com.testrpc.msm.interfaces.IMSMService|getRandom|1|2|3|4|0|
Warning: URL Host: 192.168.2.25 vs. 192.168.2.25
SSL sessID length = 16
Response payload (len = 3116):
<!– –>
TESTRPC
TESTRPC
Loading…
Javascrip
t is required.
TESTRPC ¬ 2010
var _app = navigator.appName;
if (_app == ‘Microsoft Internet Explorer’) {
document.write(”,
”,
”,
”);
}
else {
document.write(”,
”);
}
statusCode = 200
Exception in thread “main” com.google.gwt.user.client.rpc.InvocationException: E
xception while invoking the remote service com.testrpc.msm.interfaces.IMSMService.
getRandom
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:180)
at $Proxy0.getRandom(Unknown Source)
at callgwtcpc.main(callgwtcpc.java:30)
Caused by: java.lang.NumberFormatException: For input string: ”
”);
}
”
at java.lang.NumberFormatException.forInputString(NumberFormatException.
java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)
at SyncClientSerializationStreamReader.readInt(SyncClientSerializationSt
reamReader.java:439)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader
.prepareToRead(AbstractSerializationStreamReader.java:38)
at SyncClientSerializationStreamReader.prepareToRead(SyncClientSerializa
tionStreamReader.java:340)
at RemoteServiceSyncProxy.createStreamReader(RemoteServiceSyncProxy.java
:109)
at RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:172)
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:159)
… 2 more
Hello, this is indeed very nice tool, however I suggest to put gdata library as one of requirements, it took me quite some time to find out why it didn’t work, until I found issues mentioned here.
Hi. I tried SyncProxy and it worked great!
Just a small note – it gave me java.lang.ClassNotFoundException: com.google.gdata.client.GoogleAuthTokenFactory
I had to add gdata-core-1.0.jar to the path to fix it.
Hi, all,
I never got SyncProxy work in my environment/application.
I believe I missed something.
I saw other people posted their success of running SyncProxy.
Could someone post their java main program and remoteServiceURL and
requestData ?(I posted my ones below)
I tried another service, still no success,
This time it is just a http site, not a https site.
I always got the same error :
C:\si_gwt_rpc>java callgwtcpc
main
tmp_debug:doInvoke:remoteServiceURL = http://maivm011:8081/pelican/
tmp_debug:doInvoke:requestData = 5|0|4|http://maivm011:8081/pelican/|D468CB230ACD7523DA1427322A174D7F|com.testrpc.testrpcnet.pelican.client.PelicanService|getDatafileNames|1|2|3|4|0|
Response payload (len = 2414):
…
tmp_debug:doInvoke: = statusCode 200
tmp_debug:doInvoke: encodedResponse CTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Tra
nsitional//EN”>
…
tmp_debug:doInvoke: 5
java.lang.NumberFormatException: For input string: ” or –>
…
at java.lang.NumberFormatException.forInputString(NumberFormatException.
java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)
at SyncClientSerializationStreamReader.readInt(SyncClientSerializationSt
reamReader.java:439)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader
.prepareToRead(AbstractSerializationStreamReader.java:38)
at SyncClientSerializationStreamReader.prepareToRead(SyncClientSerializa
tionStreamReader.java:340)
at RemoteServiceSyncProxy.createStreamReader(RemoteServiceSyncProxy.java
:99)
at RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:155)
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:159)
at $Proxy0.getDatafileNames(Unknown Source)
at callgwtcpc.main(callgwtcpc.java:36)
tmp_debug:doInvoke: 4
exception : com.google.gwt.user.client.rpc.InvocationException: Exception while
invoking the remote service com.testrpc.testrpcnet.pelican.client.PelicanService.get
DatafileNames
———-callgwtcpc.java(begin)———————
import com.testrpc.testrpcnet.pelican.client.PelicanService;
import com.testrpc.testrpcnet.pelican.shared.PelicanDatafileNames;
public class callgwtcpc
{
private static PelicanService rpcService = null;
public static void main(String[] argv)
{
rpcService = (PelicanService)SyncProxy.newProxyInstance(PelicanService.class,
“http://maivm011:8081/pelican/”, “”);
System.out.println(“main”);
try
{
PelicanDatafileNames result = rpcService.getDatafileNames();
String[] aGenericFileNames = result.getGenericFileNames();
System.out.println(“getGenericFileNames[0] : ” + aGenericFileNames[0]);
} catch (Exception e)
{
System.out.println(“exception : ” + e);
}
}
}
———-callgwtcpc.java(end)———————
The problem is on remoteServiceRelativePath.
I saw in your code:
rpcService = (PelicanService)SyncProxy.newProxyInstance(PelicanService.class,
“http://maivm011:8081/pelican/”, “”);
with empty remoteServiceRelativePath.
It means SyncProxy will send and get data from http://maivm011:8081/pelican/. It may be not correct.
The remoteServiceRelativePath should be the servlet url mapping in your web.xml.
For example, your web.xml may be as below
PelicanService
com.testrpc.testrpcnet.pelican.server.PelicanServiceImpl
Please take note of PelicanServiceURL
The client code:
rpcService = (PelicanService)SyncProxy.newProxyInstance(PelicanService.class,
“http://maivm011:8081/pelican/”, “PelicanServiceURL”);
Hope this help.
Hi, Trung,
Thank you very much for your reply.
I tried your suggestions, still no success.
Actually I tried various combinations, no luck.
I posted my web.xml below, could you help me to find out why my program did not work ?
C:\si_gwt_rpc>java callgwtcpc
main
tmp_debug:doInvoke:remoteServiceURL = http://maivm011:8081/pelican/pelicanservic
e
tmp_debug:doInvoke:requestData = 5|0|4|http://maivm011:8081/pelican/|D468CB230ACD7523DA1427322A174D7F|com.testrpc.testrpcnet.pelican.client.PelicanService|getDatafileNames|1|2|3|4|0|
tmp_debug:doInvoke: 2
java.io.FileNotFoundException: http://maivm011:8081/pelican/pelicanservice
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstruct
orAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingC
onstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.j
ava:1368)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpU
RLConnection.java:1362)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLCon
nection.java:1016)
at RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:136)
at RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.
java:159)
at $Proxy0.getDatafileNames(Unknown Source)
at callgwtcpc.main(callgwtcpc.java:38)
Caused by: java.io.FileNotFoundException: http://maivm011:8081/pelican/pelicanse
rvice
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLCon
nection.java:1311)
at sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(HttpURL
Connection.java:2226)
at CookieManager.storeCookies(CookieManager.java:73)
at RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:134)
… 3 more
tmp_debug:doInvoke: 4
exception : com.google.gwt.user.client.rpc.InvocationException: Exception while
invoking the remote service com.testrpc.testrpcnet.pelican.client.PelicanService.get
DatafileNames
————web.xml(start)———————-
pelicanServlet
com.testrpc.testrpcnet.pelican.server.PelicanServiceImpl
pelicanServlet
/pelican/pelicanservice
Pelican.html
Pelican Home
pelican_home
/opt/pelican
java.lang.String
————web.xml(end)———————-
————main program(start)———————-
import com.testrpc.testrpcnet.pelican.client.PelicanService;
import com.testrpc.testrpcnet.pelican.shared.PelicanDatafileNames;
public class callgwtcpc
{
private static PelicanService rpcService = null;
public static void main(String[] argv)
{
rpcService = (PelicanService)SyncProxy.newProxyInstance(PelicanService.class,
// “http://maivm011:8081/pelican/”, “PelicanService”);
// “http://maivm011:8081/pelican/”, “PelicanService”, “D468CB230ACD7523DA1427322A174D7F”);
// “http://maivm011:8081/pelican/”, “”, “D468CB230ACD7523DA1427322A174D7F”);
// “http://maivm011:8081/”, “PelicanService”, “D468CB230ACD7523DA1427322A174D7F”);
// “http://maivm011:8081/”, “pelicanservice”);
// “http://maivm011:8081/pelican/”, “”);
// “http://maivm011:8081/”, “pelican/pelicanservice”);
// “http://maivm011:8081″, “/pelican/pelicanservice”);
“http://maivm011:8081/pelican/”, “pelicanservice”);
// “htp://maivm011:8081/pelican/”, “pelicanservice”, “D468CB230ACD7523DA1427322A174D7F”);
// “http://maivm011:8081/”, “pelicanservice”, “D468CB230ACD7523DA1427322A174D7F”);
// “http://maivm011:8081/”, “pelican”, “D468CB230ACD7523DA1427322A174D7F”);
// “http://maivm011:8081/pelicanservice”, “pelicanservice”, “D468CB230ACD7523DA1427322A174D7F”);
// “http://maivm011:8081/pelican//pelicanservice”, “pelicanservice”, “33B97F40B97F77CA20CB4FF41424DAAF”);
/*
try
{
SyncProxy.loginGAE(“http://maivm011:8081″, “”, “”, “”);
} catch (Exception e)
{
System.out.println(“login GAE exception : ” + e);
}
*/
System.out.println(“main”);
try
{
PelicanDatafileNames result = rpcService.getDatafileNames();
String[] aGenericFileNames = result.getGenericFileNames();
System.out.println(“getGenericFileNames[0] : ” + aGenericFileNames[0]);
/*
LoginResponse result = rpcService.login(“hello”);
*/
} catch (Exception e)
{
System.out.println(“exception : ” + e);
}
}
}
————main program(end)———————-
post web.xml again, added comment symbol to avoid xml tag.
————web.xml(start)———————-
//
//
//
//
//
//
//
// pelicanServlet
// com.testrpc.testrpcnet.pelican.server.PelicanServiceImpl
//
//
//
// pelicanServlet
// /pelican/pelicanservice
//
//
//
//
// Pelican.html
//
//
//
// Pelican Home
// pelican_home
// /opt/pelican
// java.lang.String
//
//
//
//
————web.xml(end)———————-
re-posted againg, replace “” with “]”
————web.xml(start)———————-
[?xml version="1.0" encoding="UTF-8"?]
[!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd"]
[web-app]
[!-- Servlets --]
[servlet]
[servlet-name]pelicanServlet[/servlet-name]
[servlet-class]com.testrpc.testrpcnet.pelican.server.PelicanServiceImpl[/servlet-class]
[/servlet]
[servlet-mapping]
[servlet-name]pelicanServlet[/servlet-name]
[url-pattern]/pelican/pelicanservice[/url-pattern]
[/servlet-mapping]
[!-- Default page to serve --]
[welcome-file-list]
[welcome-file]Pelican.html[/welcome-file]
[/welcome-file-list]
[env-entry]
[description]Pelican Home[/description]
[env-entry-name]pelican_home[/env-entry-name]
[env-entry-value]/opt/pelican[/env-entry-value]
[env-entry-type]java.lang.String[/env-entry-type]
[/env-entry]
[/web-app]
————web.xml(end)———————-
Hi,
This is great work and thanks to you guys.
I have few issues when trying to write a standalone java program that can connect to the remote service.
Infact remoteService.getProperties() returns the results, but get the exception.
1. Exception in thread “main” com.google.gwt.user.client.rpc.InvocationException: Exception while invoking the remote service edu.ucsb.eucalyptus.admin.client.EucalyptusWebBackend.getProperties
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:173)
at $Proxy0.getProperties(Unknown Source)
at euca.main(euca.java:23)
Caused by: java.lang.IllegalAccessError: tried to access class com.google.gwt.user.server.rpc.impl.SerializabilityUtil from class com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.deserialize(SyncClientSerializationStreamReader.java:353)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:61)
at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter$ResponseReader$8.read(RequestCallbackAdapter.java:104)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:206)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:159)
2. When I call a different method that accepts an object as a parameter, i get the following error, Serialization doesnot seem to work
Exception in thread “main” com.google.gwt.user.client.rpc.InvocationException: Exception while invoking the remote service edu.ucsb.eucalyptus.admin.client.EucalyptusWebBackend.addUserRecord
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:173)
at $Proxy0.addUserRecord(Unknown Source)
at euca.main(euca.java:26)
Caused by: java.lang.IllegalAccessError: tried to access class com.google.gwt.user.server.rpc.impl.SerializabilityUtil from class com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamWriter
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamWriter.serializeClass(SyncClientSerializationStreamWriter.java:470)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamWriter.serializeImpl(SyncClientSerializationStreamWriter.java:411)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamWriter.serialize(SyncClientSerializationStreamWriter.java:348)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:129)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.writeParam(RemoteServiceInvocationHandler.java:246)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:133)
… 2 more
Any pointers guys ?
i solved it guys, the error was due to having different versions of gwt jar during compilation and run time.
Great Post,
Thanks,
Rufus
When testing a GWT code, the async simulation is quite handy. However, I do indeed want to put some synchronousity in it when testing. Let’s say, I click a button that invokes a service and when got the results it presents them in a list. I my test I want to check the number of items I got in the list. To do this properly, I have to wait for the async service to finish before I do my assertion.
To achieve this I extended the invocation handler to keep track of async service invocations done by a specific thread and let that thread join its async service invocation threads.
If anyone interesed, I’ll post the code (quite simple thought).
Hi Gabor Farkas,
Yes, please post the code.
Are cookies shared between many proxy instances within one JVM?
For example:
service1.login(“”,”"); <– invocation of service 1initiates cookie
service2.fetchImportantData("") <– cookie initiated in service1 invocation is reused during service2 invocation (sends all actual cookie values)
Is this possible?
Thx for reply.
Yes, cookies are shared between SyncProxy instances within one JVM.
And please note, cookies are stored in memory only.
Hope this help
Thx for reply, i have another question now
In our webApp we have resources with constrained access – standard form based authentication, which means we have to first login using POST and then we can use GWT services.
This means in our integration tests we need to first login with POST (using httpclient for example), grab the cookies returned after authentication and push them inside CookieManager in RemoteServiceSyncProxy.
Is there any possibility to achieve this without using reflection? Probably not, but its always better to ask first…
Method getDomainFromHost in class CookieManager makes some ugly work with doted hosts, for example:
192.168.0.1 -> 168.0.1
I think it is not a desired behavior
Trung, thanks a lot for this great tool.
I’ll share my experience. I use objectify and my types were not being sent from the server, I was getting “type was not assignable” serialization exceptions. I had to:
-Initizalize my service in a slightly different way, as: myService = (MyService) SyncProxy.newProxyInstance(MyService.class,
“http://127.0.0.1:8888/my_app/”, “my_serv”);
-Copy my .gwt.rpc file to “null.gwt.rpc”, since the strongname that the server receives when the call comes from the test class is “null”
And it works…
I use sync proxy with junit. Make sure to set fork=yes in the junit task. Syncproxy was not picking up the correct classpath without it.
Hi,
i get this error
java.lang.NoClassDefFoundError: com/google/gdata/client/GoogleAuthTokenFactory
at de.megapharm.mm.web.testdata.RPCServiceTest.(RPCServiceTest.java:30)
Have you a idea ?
Thank You
SyncProxy depends in gdata java client, thus download it from code.google.com
Hope this help
First, thanks for some great software. This is great to have.
Here are collection of notes I had to go through to get this to work (including notes from people here):
1. Get the Google Code libraries
———————————–
http://code.google.com/p/gdata-java-client/downloads/list
You want the Google Data java client.
Add the jar file: jdata-core-1.0.jar to your classpath (or latest version)
2. Change the Example (as Ricardo mentions above)
———————————————–
A “/” is missing between the base URL and the service name.
(MyService.class, “http://127.0.0.1:8888/my_app/”, “my_serv”); (note the “/” after my_app)
3. Serialization Policy
————————————
- Some classes will not serialize without the IsSerializable interface (although GWT doesn’t require it). Just add them.
- In order to serialize a class to/from a service, it must appear in at least one method of the service both as input and output.
- Example: MyClass dummyMethod(MyClass input);
- Without the above, either serialization or deserialization will fail.
- For example: void myMethod(MyInputClass input)
– In this case, serialization will fail because the serialization policy only expects to deserialize the class and the serialization on the client side will fail.
- If you see serialization policy exceptions you may want to follow this step.
4. Add the GWT application directory to classpath
—————————————–
The GWT compiled files directory is required for proper serialization. The directory contains multiple files like this: 694BD6C5E9CCB9810670C827B93E270A.gwt.rpc and other files of type *.gwt.rpc, *.cache.png, *.cache.html
The files of type *.gwt.rpc are the serialization policy for your classes and without this directory on the classpath the serialization will fail.
Also, note that the files are only updated after you compile the GWT client files. The eclipse (IDE) compilation does not update these files.
@Piotr Szaranski:
I had the same issue with authentication, and I also was looking for more robust session management. I logged:
http://code.google.com/p/gwt-syncproxy/issues/detail?id=6
with an attached patch that while perhaps still a little rough around the edges provides support for plugging in login code.
Hi,
I tried using syncproxy with a GWT server which has been deployed. I get an exception in the server that The serialization policy file /8D6FAE24121B4699D974BC526D8B0DAE.gwt.rpc was not found did you forget to include it in this deployment? .
What needs to be done to solve this problem?
Thanks
hi, having trouble testing the greet service in gwt 2.1.
you say that: ” … SyncProxy includes test suite (see the Java source file com.gdevelop.gwt.syncrpc.test.RPCSyncSuite …” but i can ot find that file in any of the downloads on this page.
my test case (please see below) gets into doinvoke where it sends the request and gets the response. the encoded response starts with: “\r\n … ” so it looks like it got the html.
but doinvoke is not happy with this and does a: throw new InvocationException(“Unknown response ” + encodedResponse);
do i need to load load the html myself or something and then try the rpc call?
any pointers will be appreciated.
thanks
package p;
import junit.framework.TestCase;
import org.junit.*;
import com.gdevelop.gwt.syncrpc.SyncProxy;
import com.google.gwt.core.client.GWT;
import p.client.*;
import p.shared.*;
//http://www.gdevelop.com/w/blog/2010/01/10/testing-gwt-rpc-services/
public class GreetingServiceTest extends TestCase {
private static GreetingService rpcService = (GreetingService) SyncProxy.newProxyInstance(GreetingService.class, “http://127.0.0.1:8888/Reasx.html?gwt.codesvr=127.0.0.1:9997″, “greet”);
public void testGreeting() {
String result = rpcService.greetServer(“SyncProxy”);
assertTrue((result != null) && (result.startsWith(“Hello, SyncProxy”)));
}
}
Because you are using URL http://127.0.0.1:8888/Reasx.html?gwt.codesvr=127.0.0.1:9997, the server should return a html response.
You should create new Proxy instance by:
SyncProxy.newProxyInstance(GreetingService.class, “http://127.0.0.1:8888/greetingApp″, “greet”);
For com.gdevelop.gwt.syncrpc.test.RPCSyncSuite: it is now RPCSyncTestSuite.java and in the repository at
http://code.google.com/p/gwt-syncproxy/source/browse/#svn/trunk/test/com/gdevelop/gwt/syncrpc/test
i can’t find the source for com.gdevelop.gwt.syncrpc.test.RPCSyncSuite
does anyone know where it lives?
thanks
Hello!
I created simple gwt project by maven and deployed it on server.
For testing it I wrote simple test:
public class RPCtest extends TestCase {
public void testGreeting() {
System.out.println(“begin”);
GreetingService rpcService = (GreetingService) SyncProxy.newProxyInstance(GreetingService.class,
“http://192.168.9.144:8080/test-rpc”, “/Enter/greet”);
String result = rpcService.greetServer(“GWT User”);
System.out.println(result);
}
public void testGreetingAsync() {
System.out.println(“begin_async”);
GreetingServiceAsync rpcService = (GreetingServiceAsync) SyncProxy.newProxyInstance(GreetingServiceAsync.class,
“http://192.168.9.144:8080/test-rpc”, “/Enter/greet”);
rpcService.greetServer(“GWT User”, new AsyncCallback() {
public void onFailure(Throwable ex) {
System.out.println(“fault!”);
ex.printStackTrace();
}
public void onSuccess(String result) {
System.out.println(result);
}
});
}
}
Result is
begin
Hello, GWT User!I am running Apache Tomcat/6.0.20.It looks like you are using:Java/1.6.0_20
begin_async
fault!
com.google.gwt.user.client.rpc.InvocationException: IOException
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:167)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler$1.run(RemoteServiceInvocationHandler.java:151)
Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://192.168.9.144:8080/test-rpc/Enter/greet
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1368)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1362)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1016)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:141)
… 1 more
Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://192.168.9.144:8080/test-rpc/Enter/greet
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1313)
at sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(HttpURLConnection.java:2226)
at com.gdevelop.gwt.syncrpc.CookieManager.storeCookies(CookieManager.java:73)
at com.gdevelop.gwt.syncrpc.DefaultSessionManager.handleResponseHeaders(DefaultSessionManager.java:29)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:139)
… 1 more
What is wrong? Thanks.
Hi Kirill,
In the stack track:
Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://192.168.9.144:8080/test-rpc/Enter/greet
Check your server side by opening http://192.168.9.144:8080/test-rpc/Enter/greet in your web browser.
Hope this help
Hello,
It seems that the rpc call is failling when returning a Custom object (Class that wrap 2 string and one integer), when the rcp returns a string it works fine, but with the first case I’m getting this :
Exception while invoking the remote service co.com.sura.soatvl.client.services.IConsultasService.consultarTexto
com.google.gwt.user.client.rpc.InvocationException: Exception while invoking the remote service co.com.sura.soatvl.client.services.IConsultasService.consultarTexto
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:185)
at $Proxy0.consultarTexto(Unknown Source)
at co.com.sura.soatvl.client.StressTest.loadRPC(StressTest.java:33)
at co.com.sura.soatvl.client.StressTest.main(StressTest.java:46)
Caused by: com.google.gwt.user.client.rpc.InvocationException: Error while performing serialization
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:169)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:164)
... 3 more
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type 'co.com.sura.soatvl.shared.dto.Texto' was not included in the set of types which can be deserialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be deserialized.
at com.google.gwt.user.server.rpc.impl.StandardSerializationPolicy.validateDeserialize(StandardSerializationPolicy.java:158)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.deserialize(SyncClientSerializationStreamReader.java:360)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter$ResponseReader$8.read(RequestCallbackAdapter.java:104)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:158)
... 4 more
Do you know what I’m doing wrong and how and how to fix it?
Thanks in advance.
It seem that the SyncProxy could not find and load *.gwt.rpc files. These *.gwt.rpc define a white-list of classes can be instantiated and serialized/deserialized for your RemoteService. Java primitives (String, long, int, etc) by default are included in the white-list, that why the rcp returns a string it works fine but not for the custom object.
To solve this, copy $war//*.gwt.rpc files to you test classpath.
Hope this help.
I have already linked those *.gwt.rpc files, but the problem seems to be that my class have permission to serialize but no to deserialize.
co.com.sura.soatvl.shared.dto.Texto, true, true, false, false, co.com.sura.soatvl.shared.dto.Texto/2912884571, 2912884571
My workaround was to change all of those false to true, but I don´t know how safe/unsafe is that.
BTW I’m using GWT 2.1
PS: Thanks for your response.
Hi,
I have the same problem and am unable to solve it, unless I change false to true in the gwt.rpc files I copy to the SyncProxy client. This results in the serialization policy error showing on the server (which works with the unmodified files) rather than the client.
Did anyone find a solution to this?
Thanks,
Julian
Using Gwt 2.1, seeing the following error because PagingLoadConfig is an interface. Just not sure why this error occurs.
Exception in thread “main” java.lang.NoClassDefFoundError: com/extjs/gxt/ui/client/data/PagingLoadConfig
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2444)
at java.lang.Class.privateGetPublicMethods(Class.java:2564)
at java.lang.Class.getMethods(Class.java:1427)
at sun.misc.ProxyGenerator.generateClassFile(ProxyGenerator.java:426)
at sun.misc.ProxyGenerator.generateProxyClass(ProxyGenerator.java:323)
at java.lang.reflect.Proxy.getProxyClass(Proxy.java:518)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:598)
at com.gdevelop.gwt.syncrpc.SyncProxy.newProxyInstance(SyncProxy.java:119)
at com.gdevelop.gwt.syncrpc.SyncProxy.newProxyInstance(SyncProxy.java:155)
at exploit.main(exploit.java:10)
Caused by: java.lang.ClassNotFoundException: com.extjs.gxt.ui.client.data.PagingLoadConfig
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
… 22 more
Removed the RPC methods that implemented this interface and it doesn’t fail anymore.
Hello,
Is there any testing tool which will test the GWT RPC. In my application we are building the services first and need to test the services before integrating to UI, can someone help?
Regards,
Amol
I can run on the Eclipse jetty server port 8888 fine
domain= http://localhost:8888/webfrontend/
path=PILService
(this is after I added a servlet tag to my webfrontend.gwt.xml file
However when I try to run on Apache 8080
I get a FileNotFoundException
my web.xml looks like this:
[web-app]
[!-- Servlets --]
[servlet]
[servlet-name]PILServiceServlet[/servlet-name]
[servlet-class]il.ac.haifa.pil.webfrontend.server.PilServiceImpl[/servlet-class]
[/servlet]
[servlet-mapping]
[servlet-name>PILServiceServlet[/servlet-name]
[url-pattern]/webfrontend/PILService[/url-pattern]
[/servlet-mapping>
[!-- Default page to serve --]
[welcome-file-list]
[welcome-file]WebFrontEnd.html[/welcome-file]
[/welcome-file-list]
[/web-app]
Any suggestions
Thanks
For some reason need to double the app name
so change path to webfrontend/PILSERVICE
Hi Trung,
I’ve just started using syncproxy and it works great. I’m trying to use it with GWTEventService, and for some reason the the gwt.rpc file says it can’t deserialize one of the classes returned by the service (DefaultDomainEvent). I checked out your code so I could ignore the deserialization error, only to find that you’ve already done it in revision 23. Any ideas when this change will be released?
Many thanks, and great work,
Ian
Hi,
This is really cool. But i have a problem. I created a GWT application in eclipse and success fully executed with default server. I tried to deploy in tomcat5 server and tried to access the remote method from my java application. This is failed. Please help me to find out the reason. I got the following error:
com.google.gwt.user.client.rpc.InvocationException: Exception while invoking the remote service anoop.web_service.client.GreetingService.greetServer
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:185)
at $Proxy0.greetServer(Unknown Source)
at anoop.web_service.client.AppMain.main(AppMain.java:19)
Caused by: com.google.gwt.user.client.rpc.InvocationException: IOException
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:167)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:164)
… 2 more
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:133)
… 3 more
I’ve just tried using this against GWT 2.3 and got an error “Expecting version 6 from server, got 7″. I’ve managed to recompile from source and it’s resolved that issue and left me with the following:
com.google.gwt.user.client.rpc.InvocationException: Exception while invoking the remote service au.com.cgu.harvest.web.client.request.IRequestDispatcherService.dispatch
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:194)
at $Proxy36.dispatch(Unknown Source)
at au.com.cgu.harvest.transaction.JettyTest.startJetty(JettyTest.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: Type ‘au.com.cgu.harvest.request.RetrieveDocumentRequest’ was not assignable to ‘com.google.gwt.user.client.rpc.IsSerializable’ and did not have a custom field serializer. For security purposes, this type will not be deserialized.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.instantiate(SyncClientSerializationStreamReader.java:519)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.deserialize(SyncClientSerializationStreamReader.java:372)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:165)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:173)
… 24 more
I have confirmed that my *.gwt.rpc is on the classpath (and have tried renaming it to null as a previous post suggested).
I’m now attempting to get the tests (from svn) to compile so I can work through this issue but can’t work out what the gwt-dev-? dependency is for all tests in the com.gdevelop.gwt.syncrpc.test package.
Please point me in the right direction if you can. Happy to contribute patches back
Ben.