GWT SyncProxy Testing - gwt

I create a new Web Application Project with the standard GWT example. Then i want to test the greetingserviceimpl with the following test class. I don't know where is the problem. I also upload the project: http://ul.to/1pz1989y
public class RPCTest extends GWTTestCase {
#Override
public String getModuleName() {
// TODO Auto-generated method stub
return "de.GreetingTest";
}
public void testGreetingAsync() {
GreetingServiceAsync rpcService = (GreetingServiceAsync) SyncProxy.newProxyInstance(GreetingServiceAsync.class,"http://127.0.0.1:8888/GreetingTest.html?gwt.codesvr=127.0.0.1:9997");
rpcService.greetServer("GWT User", new AsyncCallback<String>() {
public void onFailure(Throwable ex) {
ex.printStackTrace();
fail(ex.getMessage());
}
public void onSuccess(String result) {
assertNotNull(result);
finishTest();//
}
});
delayTestFinish(1000);
}
}
Validating newly compiled units
Ignored 1 unit with compilation errors in first pass.
Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
[ERROR] Line 17: No source code is available for type com.gdevelop.gwt.syncrpc.SyncProxy; did you forget to inherit a required module?
[ERROR] Unable to find type 'de.client.RPCTest'
[ERROR] Hint: Previous compiler errors may have made this type unavailable
[ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly

Your rpc service is async - it doesn't finish by the time that the testGreetingAsync method returns. GWTTestCase (but you are extending TestCase, you should probably change this) has support for this though - call delayTestFinish at the end of the method to indicate that the test is async. Then, call finishTest once you are successful.
public class RPCtest extends GWTTestCase {
public void testGreetingAsync() {
GreetingServiceAsync rpcService = (GreetingServiceAsync) SyncProxy.newProxyInstance(GreetingServiceAsync.class,"http://127.0.0.1:8888/Tests.html?gwt.codesvr=127.0.0.1:9997");
rpcService.greetServer("GWT User", new AsyncCallback() {
public void onFailure(Throwable ex) {
//indicate that a failure has occured
ex.printStackTrace();
fail(ex.getMessage());//something like this
}
public void onSuccess(Object result) {
//verify the value...
assertNotNull(result);
//Then, once sure the value is good, finish the test
finishTest();//This tells GWTTestCase that the async part is done
}
});
delayTestFinish(1000);//1000 means 'delay for 1 second, after that time out'
}
}
Edit for updated question:
The test class 'de.RPCTest' was not found in module 'de.GreetingTest'; no compilation unit for that type was seen
Just like your regular GWT code must be in a client package, so must your GWTTestCase code - this also gets run as JavaScript so it can properly be tested as if it were in a browser. Based on the error, I'm guessing your EntryPoint, etc are in de.client - this test should be there too.

Related

How to use dependency injection in JUnit for Eclipse E4 plugin projects

When I set up a context in a JUnit test case to enable testing of a test object (E4 plugin project), which uses dependency injection for a service IMyServiceInterface, the result is always the same:
InjectionException: Unable to process "MyTestObject.myServiceInterface" no actual value was found for the argument IMyServiceInterface".
My idea is to set up a Eclipse context in a test case within JUnit and inject the test object together with its stubbed dependencies (i.e. not mocked).
The test object is a class used in a E4 plugin project and have a reference to an injected service interface.
I've tried several ways of setting up a context in a JUnit test case (with both ContextInjectionFactory.make(...) and InjectorFactory.getDefault().make(...)) to enable testing of the test object.
Here is a simplification of my test object (E4 plugin project) with its two dependencies; IMyServiceInterface and IMyPartInterface:
#Creatable
#Singleton
public class MyTestObject {
#Inject IMyServiceInterface myServiceInterface;
public void myMethod(IMyPartInterface myPartInterface) {
this.myServiceInterface.update();
myPartInterface.set();
}
}
Here is a simplification of my test case (JUnit project):
class AllTests {
#Test
void myTestCase() {
InjectorFactory.getDefault().make(MyPart_Stub.class, null);
InjectorFactory.getDefault().make(MyService_Stub.class, null);
MyTestObject myTestObject = InjectorFactory.getDefault().make(MyTestObject.class, null);
}
}
Here are my stubbed dependencies (JUnit project):
public class MyService_Stub implements IMyServiceInterface {
public void update() {
}
}
public class MyPart_Stub implements IMyPartInterface {
public void set() {
}
}
When I run the test case I get: InjectionException: Unable to process "MyTestObject.myServiceInterface" no actual value was found for the argument IMyServiceInterface".
Finally I've understood whats wrong. I haven't been aware of the fact that ContextInjectionFactory.make(...) only creates an object (i.e. it doesn't inject it in the context as well). To inject the created object I also have to use the set method in the context. This is how I got my basic example to work:
class AllTests {
#Test
void myTestCase() {
IEclipseContext context = EclipseContextFactory.create();
IMyPart myPart_Stub = ContextInjectionFactory.make(MyPart_Stub.class, context);
context.set(IMyPart.class, myPart_Stub);
IMyService myService_Stub = ContextInjectionFactory.make(MyService_Stub.class, context);
context.set(IMyService.class, myService_Stub);
MyTestObject myTestObject = ContextInjectionFactory.make(MyTestObject.class, context);
context.set(MyTestObject.class, myTestObject);
}
}

Can't inject EPartService

In my bundle activator I try to inject fields 'IEventBroker' and 'EPartService'. But injected only first. Code follows:
#Inject
IEventBroker m_broker;
#Inject
EPartService m_part_service;
public void start(BundleContext context) throws Exception {
IEclipseContext service_context = EclipseContextFactory.getServiceContext(context);
ContextInjectionFactory.inject(this, service_context);
boolean contains = service_context.containsKey(EPartService.class);
// contains is always "true", but m_part_service is always "null"
// all follows invocations returns "null" too
//
// service_context.get(EPartService.class);
// service_context.getActiveLeaf().getActive(EPartService.class);
// service_context.getActiveLeaf().getLocal(EPartService.class);
// context.getServiceReference(EPartService.class);
// m_broker always non-null
m_broker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE, new EventHandler()
{
#Override
public void handleEvent(Event event)
{
// ... bla bla bla
}
});
}
In internal lists of IEclipseContext I found EPartService.
Can you help me? What I did wrong?
Bundle activators are not injected so you can't use #Inject.
The context returned by EclipseContextFactory.getServiceContext has very limited contents and can't be used to access things like EPartService.
In any case the bundle activator generally isn't even run until something else in your plugin is used, so it would be too late the see the startup complete message anyway.
So all this means you can't do what you want in the bundle activator start method.
To get notified about the app startup complete event you can use the application LifeCycle class or define an AddOn - both these classes are injected.
In those classes use a method like:
#Optional
#Inject
public void appStartupComplete(#UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE)
org.osgi.service.event.Event event)

GWT : Getting a 404 error when unit testing RequestBuilder

I use the GWT RequestBuilder, and for testing purposes, I'd like to load a json file in the server.
It works perfectly with the DevMode, but throw a 404 error with GWTTestCase.
With RPC, there is a fix adding <servlet path=".." class="..."/>, but what can I do with static content ?
I could easily use #TextResource, but it's not the goal of my UnitTest (which is in fact a functionnal test)
Static resources can be bundled with a module by putting them in the module's public path.
I used (once again) Thomas's answer to resolve the problem. My module is io.robusta.fora.comments.Comment.gwt.xml and I've put my user.json file in the io.robsuta.fora.comments.resources package.
I had so to add in Comment.gwt.xml file : <public path="resources"/>
Then the GWTTestCase is straightforward :
public class GwtRestClientTest extends GWTTestCase{
#Override
public String getModuleName() {
return "io.robusta.fora.comments.Comments";
}
public void testGET(){
String base = GWT.getModuleBaseURL();
System.out.println(base); //-> http://192.168.0.10:53551/io.robusta.fora.comments.Comments.JUnit/
GwtRestClient client = new GwtRestClient(base); //base url
AsyncCallback<String> cb = new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
System.out.println(result);//->{id:1,email:"jo#robusta.io"}
finishTest();
}
#Override
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
};
client.GET("user.json", null, cb);//fetch my json file with no params
delayTestFinish(3000);
}
}

error when i run my RMI project

what do i have to do when I have this error:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException
I added the path of the bin in JDK in the properties of "MY computer": this one "C:\Program Files\Java\jdk1.6.0_19\bin"
and I entered to run-cmd-
cd C:\Users\user\Documents\NetBeansProjects\CountRMI\src\countrmi
start rmiregistry
and i run the server, so this error appear
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException
Thank u
Consider looking at the Cajo project. It wraps RMI so you don't have to worry about starting rmi registries and the such.
See the example below from one of the Cajo wiki pages
Duck.java
public interface Duck {
boolean looks();
boolean walks();
boolean talks();
}
DuckServer.java
import gnu.cajo.invoke.Remote;
import gnu.cajo.utils.ItemServer;
public class DuckServer implements Duck {
public boolean looks() {
System.out.println("hi there!");
return true;
}
public boolean walks() {
System.out.println("waddle waddle");
return true;
}
public boolean talks() {
System.out.println("quack quack!");
return true;
}
public static void main(String args[]) throws Exception { // simple unit test
Remote.config(null, 1198, null, 0); // use cajo port 1198
ItemServer.bind(new DuckServer(), "Donald");
System.out.println("duck server running");
}
}
DuckClient.java
import gnu.cajo.utils.extra.TransparentItemProxy;
public class DuckClient { // try out DuckServer
public static void main(String args[]) throws Exception {
Duck duck = (Duck)TransparentItemProxy.getItem(
"//serverHost:1198/Donald",
new Class[] { Duck.class }
);
System.out.println("looks like = " + duck.looks());
System.out.println("walks like = " + duck.walks());
System.out.println("talks like = " + duck.talks());
}
}
The time has passed, but maybe this helps someone. When you put
cd C:\Users\user\Documents\NetBeansProjects\CountRMI\src\countrmi
you are setting de path to sources files, but yo have to set this to the classes files, in this way
cd C:\Users\user\Documents\NetBeansProjects\CountRMI\build\classes
and start rmiregistry, of course
at least, it worked fine for me.

jBoss deployment of message-driven bean spec violation

I have an java EE application which has one message-driven bean and it runs fine on JBoss 4, however when I configure the project for JBoss 6 and deploy on it, I get this error;
WARN [org.jboss.ejb.deployers.EjbDeployer.verifier] EJB spec violation:
...
The message driven bean must declare one onMessage() method.
...
org.jboss.deployers.spi.DeploymentException: Verification of Enterprise Beans failed, see above for error messages.
But my bean HAS the onMessage method! It would not have worked on jboss 4 either then.
Why do I get this error!?
Edit:
The class in question looks like this
package ...
imports ...
public class MyMDB implements MessageDrivenBean, MessageListener {
AnotherSessionBean a;
OneMoreSessionBean b;
public MyMDB() {}
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
//Lookup sessionBeans by jndi, create them
lookupABean();
// check message-type, then invokie
a.handle(message);
// else
b.handle(message);
} catch (SomeException e) {
//handling it
}
}
}
public void lookupABean() {
try {
// code to lookup session beans and create.
} catch (CreateException e) { // handling it and catching NamingException too }
}
}
Edit 2:
And this is the jboss.xml relevant parts
<message-driven>
<ejb-name>MyMDB</ejb-name>
<destination-jndi-name>topic/A_Topic</destination-jndi-name>
<local-jndi-name>A_Topic</local-jndi-name>
<mdb-user>user</mdb-user>
<mdb-passwd>pass</mdb-passwd>
<mdb-client-id>MyMessageBean</mdb-client-id>
<mdb-subscription-id>subid</mdb-subscription-id>
<resource-ref>
<res-ref-name>jms/TopicFactory</res-ref-name>
<jndi-name>jms/TopicFactory</jndi-name>
</resource-ref>
</message-driven>
Edit 3:
I just removed all my jars from the project, and only re-added relevant ones (from new versions also) to put out NoClassDefFound errors.
Still the problem remains.
Edit:
Any directions, what area should I look at? My project, or jboss-configration, or the deployment settings??
org.jboss.ejb.deployers.EjbDeployer.verifier
looks for
public void onMessage(javax.jms.Message)
via some code like this (this is from JBoss5):
/**
* Check if the given message is the onMessage() method
*/
public boolean isOnMessageMethod(Method m)
{
if ("onMessage".equals(m.getName()))
{
Class[] paramTypes = m.getParameterTypes();
if (paramTypes.length == 1)
{
if (Message.class.equals(paramTypes[0]))
return true;
}
}
return false;
}
It is important that the parameter type is javax.jms.Message and nothing else, for example some subclass or superclass or some implementing class.
Your signature is public void onMessage(Message message) which looks ok on first sight.
A Class is equal only in its ClassLoader. If for some reasons javax.jms.Message is available in different classloaders in the same JVM, strange things can happen, depending on the ClassLoader of the EjbDeployer.verifier. Maybe the EjbDeployer.verifer has a access to javax.jms.Message in another ClassLoader as MyMDB. As result, both javax.jms.Message are not equal to each other, although they are the same byte-code and literally exists. The EjbVerifier will warn about missing onMessage, because javax.jms.Message on ClassLoader A is not equal to javax.jms.Message on ClassLoader B.
This can happen when libraries with javax.jms.Message is copied on wrong places on the JBoss AS. So I guess - from a distance - that there is some jars containing javax.jms.Message in wrong places on the JBoss or the EAR. For example some wrong jbossallclient.jar in the EAR.
Make sure your EAR does not contain its own copies of the javax.ejb classes (or any javax classes at all, for that matter). JBoss 4 and 6 have rather different classloading semantics, and what works on one may not work on the other. For example, if your EAR's lib contained its own copies of Message or MessageListener, then it may no longer work.
I tried it out on "JBossAS [6.0.0.20100911-M5 "Neo"]" and Eclipse Helios
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.Message;
import javax.jms.MessageListener;
#MessageDriven(
activationConfig = { #ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Topic"
) },
mappedName = "topic/A_Topic",
messageListenerInterface = MessageListener.class)
public class MyMDB implements MessageListener, MessageDrivenBean {
private static final long serialVersionUID = -4923389997501209506L;
public MyMDB() {
// TODO Auto-generated constructor stub
}
#Override
public void ejbRemove() {
// TODO Auto-generated method stub
}
#Override
public void setMessageDrivenContext(MessageDrivenContext arg0) {
// TODO Auto-generated method stub
}
#Override
public void onMessage(Message message) {
// TODO Auto-generated method stub
}
}
And this setting works. Do you have the same imports for your bean (perhaps there was an automatic import gone wrong???)