The first thing we need to do in part three is begin GWT's Remote Procedural Call (RPC) plumbing. We use the RPC calls to fire off Asynchronous events so that we can get data from our database. The calls go to the server effectively. Firstly I have made a package called com.company.client.rpc and this is where we'll make our RPC interfaces.
Firstly make a interface called TeacherService as listed below.
package com.company.client.rpc;
import java.util.List;
import com.google.gwt.user.client.rpc.RemoteService;
public interface TeacherService extends RemoteService
{
/**
* @gwt.typeArgs <com.company.client.dto.PupilDTO>
*/
public List getPupils(Integer teacherId);
}
A few things to notice here are that the interface extends RemoteService which is a GWT class and is part of the RPC plumbing. Also you'll note that the return type is not typed as in List <Object> this is because at the writing of this GWT didn't support Java 6. Also the gwt.typeArgs defines to GWT the type that we expect to get back.
Now we need to make our Async version of the interface. Make a new interface within the same packaged named TeacherServiceAsync. The Async appendage is important because GWT uses this convention to identify async classes. The code is listed below:
package com.company.client.rpc;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface TeacherServiceAsync
{
public void getPupils(Integer teacherId, AsyncCallback callback);
}
Notice that we have changed the return type to void and added a parameter to the method signature that is of type AsyncCallback this is also very important and you'll see why later. The callback parameter must always be last so if your methods take a few arguments make sureyou AsyncCallback argument is last. Now to write the classes on the server side of code. Here we will drag some useful functionality from Spring and implement Transactional Database calls.
Firstly make a package called com.company.server.gwt. Then we can create our RemoteServiceServlet. The class beginnings is listed below.
package com.company.server.gwt;
import java.util.List;
import com.company.client.dto.PupilDTO;
import com.company.client.rpc.TeacherService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
public class TeacherServiceImpl extends RemoteServiceServlet implements TeacherService
{
/**
*
*/
private static final long serialVersionUID = 1L;
public List<PupilDTO> getPupils(Integer teacherId)
{
// TODO Auto-generated method stub
return null;
}
}
Notice we can fully type our list as we are coding server side code and that the interface extends RemoteServiceServlet which is a required part of the the RPC plumbing. For now leave that class there and we will make the database code.
Make a new package called com.company.server.domain (obviously package names are up to you my convention is hazy sometimes...) I tend to work with collections of data and have a convention that server classes extend java.util.List and then we can ask for any element from the list. Firstly make an interface called Pupil Collection that extends List. You can also use java generics as I have done if required. Code below:
package com.company.server.domain;
import java.util.List;
public interface PupilCollection<T> extends List<T>
{
/**
*
* @return The list associated with the class
*/
public List<T> getList();
/**
* Populate the list for the class with some pupils
*
* @param teacherId
*/
public void getPupils(Integer teacherId);
}
Now we'll write the implementing class and this will contain the true database calls to fetch data also any delegate methods for our List object. Code listed below.
package com.company.server.domain;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;
public class PupilCollectionImpl<T> extends HibernateDaoSupport implements PupilCollection<T>
{
private List<T> list = null;
public List<T> getList()
{
return list;
}
@Transactional(readOnly=true)
public void getPupils(Integer teacherId)
{
try
{
list = getHibernateTemplate().findByNamedQueryAndNamedParam("pupilsbyid", "teacherId", teacherId);
}
catch(Exception e )
{
e.printStackTrace();
}
}
/// DELEGATE METHODS REQUIRED FOR OUR LIST ////
/// NOT IMPLEMENTED AS NOT USED BY EXAMPLE ////
public boolean add(T o)
{
// TODO Auto-generated method stub
return false;
}
public void add(int index, T element)
{
// TODO Auto-generated method stub
}
...
This is a very important class things to note are the use of the @Transactional annotation above the method. This alerts Spring that the method should be executed in one transaction. The second thing is Hibernate query call indByNamedQueryAndNamedParam("pupilsbyid", "teacherId", teacherId) pupilsbyid is our query name, teacherId as String is the parameter name and teacherID as Integer is the actual ID we are looking for.
. Now to go ahead and write our query into our mapping file.In the hibernate.cfg.xml file add the line:
<mapping resource="database.hbm.xml"/>
This allows us to use a hibernate mapping file to put our queries into. Now in the src folder create a file called database.hbm.xml code listed below
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<query name="pupilsbyid"><![CDATA[
from com.company.server.persistent.Pupil as p
where p.teacher.teacherId = :teacherId
order by p.name ]]>
</query>
</hibernate-mapping>
You can now see our query name and the parameter specification as mentioned before. This will get us all the pupils for a certain teacher.
Thats our server database code complete. Now we can go back to the unfinished RemoteServiceServlet class and use a bit of Spring magic to make the call. Firstly we need to define a bean for our PupilCollectionImpl so find the applicationContext.xml file that was created in the earlier tutorials and add the line:
<bean id="pupilCollection" class="com.company.server.domain.PupilCollectionImpl" scope="prototype">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
Now thats done we need to write a way to get the beans, make a new package called com.company.spring and add the following class
package com.company.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ContextUtil
{
private static ApplicationContext context = null;
private ContextUtil( )
{
super();
}
public static ApplicationContext getContext( )
{
// Load up our Application context
if (context == null)
{
context = new ClassPathXmlApplicationContext("applicationContext.xml") ;
}
return context;
}
}
This class is used to load our applicationContext and get any required beans. You can of course do this differently.
This allows us get access to the database methods we just wrote and also the database details through the use of referencing the session factory bean within the definition. Now to call trhe bean revisit the TeacherServiceImpl class and add the following lines:
public List<PupilDTO> getPupils(Integer teacherId)
{
List<PupilDTO> results = null;
try
{
PupilCollection<?> collection = (PupilCollection<?>) ContextUtil.getContext().getBean("pupilCollection");
collection.getPupils(teacherId);
results = new ArrayList<PupilDTO>();
for ( Iterator<?> it = collection.getList().iterator(); it.hasNext(); )
{
Pupil pupil = (Pupil) it.next();
PupilDTO dto = new PupilDTO();
BeanUtils.copyProperties(dto, pupil);
results.add(dto);
}
}
catch(Exception e)
{
e.printStackTrace();
throw new RuntimeException(e);
}
return results;
}
Notice the name of the bean we are getting pupilCollection' which we defined in our applicationContext. Is it coming together now?
Thats basically our server side code now complete. We now have some methods that we can call upon to load data. Woohoo!
The next thing to do is perform the calls from the client end somehow. For this I use an MVC approach and implement the observer
pattern as specified by the Gang of 4 Design Patterns. Firstly make a package named com.company.client.model
and in there add two interfaces Observer and Subject. Code listed below:
package com.company.client.model;
public interface Subject
{
public void addObserver( Observer o );
public void removeObserver( Observer o );
}
package com.company.client.model;
public interface Observer
{
public void update( Subject o );
public String toString();
}
Next make our model that implements Subject. This is used so that we can make the RPC calls from the client end and successfully update GUI
views. I have made a TeacherModel class that implements Subject. Code is listed below.
package com.company.client.model;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.company.client.rpc.TeacherService;
import com.company.client.rpc.TeacherServiceAsync;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
public class TeacherModel implements Subject
{
private List pupils = null;
protected ArrayList observers = null;
///// Observer Methods ////////
public void addObserver(Observer o)
{
if ( observers == null )
{
observers = new ArrayList();
}
observers.add(o);
}
public void removeObserver(Observer o)
{
if ( observers != null )
{
observers.remove(o);
}
}
public void notifyObservers()
{
Iterator it = observers.iterator();
while( it.hasNext() )
{
Observer o = ( Observer ) it.next();
o.update( this );
}
}
public void getPupils(Integer teacherId)
{
TeacherServiceAsync teacherService = (TeacherServiceAsync) GWT.create(TeacherService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) teacherService;
String moduleRelativeURL = GWT.getModuleBaseURL() + "teachers";
endpoint.setServiceEntryPoint(moduleRelativeURL);
teacherService.getPupils(teacherId, new AsyncCallback()
{
public void onFailure(Throwable caught)
{
// TODO Auto-generated method stub
}
public void onSuccess(Object result)
{
pupils = (List) result;
notifyObservers();
}
});
}
public List getPupils()
{
return pupils;
}
public void setPupils(List pupils)
{
this.pupils = pupils;
}
}
I won't go into details about the implementation of the design pattern for that read the book its worth it!
The getPupils method is the important one this is where we perform the RPC call, notice we look for a URL of "teachers" this is defined in the
gwt.xml file so lets define it now. In the MyApplication.gwt.xml file add the line:
<servlet path="/teachers" class="com.company.server.gwt.TeacherServiceImpl"/>
This makes that RPC now work. Now inspect the anonymous inner callback class in my implementation this is used to update and notify any observers on a successful call. Also note you can cast the result to the type it is meant to be. For example a save method could return a boolean.
At this stage you can test the call to ensure that it is working by simply making a new TeacherModel and calling getPupils. The final step is to write the
client GUI code. I have wrote a simply GUI that takes an ID and performs a search for pupils when the users click search, when the search has finished the view is updated in a GWT way. The code is below and may help bring things together for the whole Async way of doing things.
package com.company.client;
import java.util.Iterator;
import com.company.client.dto.PupilDTO;
import com.company.client.model.Observer;
import com.company.client.model.Subject;
import com.company.client.model.TeacherModel;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class MyApplication implements EntryPoint, Observer
{
private TeacherModel model = null;
private VerticalPanel display = null;
private VerticalPanel resultsPanel = null;
/**
* This is the entry point method.
*/
public void onModuleLoad()
{
model = new TeacherModel();
display = new VerticalPanel();
model.addObserver(this);
HorizontalPanel searchPanel = new HorizontalPanel();
final TextBox teacherIdBox= new TextBox();
final Button button = new Button("Search");
button.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
resultsPanel.add(new HTML("Searching...."));
model.getPupils(new Integer(teacherIdBox.getText()));
}
});
searchPanel.add(teacherIdBox);
searchPanel.add(button);
resultsPanel = new VerticalPanel();
display.add(searchPanel);
display.add(resultsPanel);
RootPanel.get("database").add(display);
}
public void update(Subject o)
{
if ( model.getPupils() != null && model.getPupils().size() > 0)
{
resultsPanel.clear();
for( Iterator it = model.getPupils().iterator(); it.hasNext();)
{
PupilDTO dto = (PupilDTO)it.next();
resultsPanel.add(new HTML(dto.getName()));
}
}
}
}
I hope this tutorial has helped clear up some issues. The final tutorial will explain how make the application work as a live application and not just in GWT hosted mode. The Eclipse project can be downloaded here and can be used as a template for projects. I would still urge people to read the tutorial.
Part four is now available
43 comments:
can we get the code in .zip bundle?
Hi there,
great tutorial. I very much enjoyed it. One weird thing that I can't wrap my head around is your use of
BeanUtils.copyProperties(dest, src);
I looked at the javadocs for this and they very much agree with your use, but I could not get your app to run until I used it like:
BeanUtils.copyProperties(src, dest);
Maybe that will help some people who run into my same issue, which was no output on the query for teacher id '1'.
Thanks again!
Darren
Hi, thanks for the great tutorial. Could you make the source file available? I think the link is broken.
Hi there
Thanks for the comments. I'm going to make the source code available very soon. Just waiting to get me laptop back....
When I try to do like this example, I have an error.
Can you help me?
***********
[WARN] StandardContext[]Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: Type 'org.springframework.beans.factory.BeanDefinitionStoreException' was not included in the set of types which can be serialized by this SerializationPolicy. For security purposes, this type will not be serialized.
at com.google.gwt.user.server.rpc.impl.StandardSerializationPolicy.validateSerialize(StandardSerializationPolicy.java:79)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:331)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:81)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:259)
at com.google.gwt.user.server.rpc.RPC.encodeResponse(RPC.java:574)
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:366)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:547)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:265)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:187)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
Hi there
This is a GWT error. Your server code shouldn't be on the client side as certain classes aren't included in the GWT compiler.
Have you included a package on the client side that you don't need or is not included within GWT?
Eggsy
Hi, thanks for the great tutorials, it really helped me get started with GWT.
My impression is, it's an interesting to mix mvc and observer for this type of application. When client side model becomes asynchronous which makes it to work like a publisher, then the controller becomes subscriber.
In server side there are no view, just the servlet that acts like a controller and uses hibernate objects as model.
BTW, in the tutorial, it would be more elegant if the view wasn't mixed with controller in MyApplication.
Hi romerun,
You're quite right the MVC approach in the example does mix the two and ties the model up to the controller which is definately not ideal. Since writing this I have coded a more event based method so that controllers simply fireoff events using some form of event despatcher and then whatever is listening handles the rest.
Thank you for your comments.
The reason for the BeanUtils issue (fist comment) is that you can use one of two different BeanUtils (org.apache.commons.beanutils.BeanUtils or org.springframework.beans.BeanUtils)
If you use the org.springframework.beans.BeanUtils, you have to specify your code as follows:
BeanUtils.copyProperties(src, dest);
If you use org.apache.commons.beanutils.BeanUtils (like tutorial) you should specify code like:
BeanUtils.copyProperties(dest, src);
Hope this helps!
I have done with your example and I got an error. I tried to figure out but really don't know what happen, please help. Thank you very much in advance
here is the error I'm facing
----------------------------------
[WARN] StandardContext[]Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List com.company.client.rpc.TeacherService.getPupils(java.lang.Long)' threw an unexpected exception: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:361)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:547)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:265)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:187)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at com.google.gwt.dev.shell.GWTShellServlet.service(GWTShellServlet.java:253)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
Caused by: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
at com.company.server.gwt.TeacherServiceImpl.getPupils(TeacherServiceImpl.java:29)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:528)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:265)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:187)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at com.google.gwt.dev.shell.GWTShellServlet.service(GWTShellServlet.java:253)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
Hi there
First of all I'd try searching on your client side code for the package:
org.springframework.context.ApplicationContext
If this is the case then you shouldn't be using this on the client.
The other problem it possibly looks like is that you may have not included a required jar in your lib directory of your Web application.
The package in question is in the jar file:
spring.jar and can be doownload from the springframework pages.
Ensure that the jar file is on your buildpath.
hi there,
no worries do you want to send me an email to eggsy84 **at** gmail.com, include your ServiceImpl class and I can take a look?!
Hi, thanks for the great tutorials, but i have a problem now.
Im able to retrieve data from the database but when i want to update it i dont have the id property of that object because hibernate says that the id set property must be private.
How can i solve that.
Thanks again!
Hi there,
Do you want to post your sample code here and I can try to help?
Haven't experienced that error myself.
My problem was in my POJO class, the set method for the id column was declared as protected so when i retrieve and object from the database using hibernate and try to copy that property beanutils could not do it because he could not access the method of that property.
I changed it to public and solve the problem.
And doing that i could update the data of that object after i changed other properties becouse the object had the id column setted.
thanks a lot for being interested in my problem.
I am also trying to use gwt-spring-hibernate. I use one hibernate4gwt example (proxy mode - it is similar to what u desrcibed) which works fine with shell run, but cannot start in JBOSS.
Can you share how you tune your web.xml?
Hi
I have written the fourth part of the tutorial.
You can get it at:
http://eggsylife.blogspot.com/2008/09/hibernate-spring-google-web-toolkit.html
my problem was in my java.class not in my web.xml. i'm just using tomcat not jboss so i can help you too much. the web.xml is the same as in the example
Great set of tutorials. I have tried all three of them but am getting and error in part three, when running it the developer shell give the error below. I have created my project in the same steps as described in the tutorial, so what could I be missing. I also downloaded the source code and I compared some classes they look the same. Thanks in advance for your help and the great tutorial
[ERROR] Deferred binding result type 'com.company.client.rpc.TeacherServiceAsync' should not be abstract
Hi there,
Thank you for your comments.
Can you post your code for the TeacherServiceAsync, Teacher Service interfaces?
And the TeacherServiceImpl class?
Can use http://pastebin.com/ to post code if you like
I just found found my problem...I
was using "...GWT.create(TeacherServiceAsync.class);"
instead of "...GWT.create(TeacherService.class);"
in my model class. Changing that fixed it.
Thanks a lot and again I loved the way you have setup the tutorial, easy to follow and understand.
Hi there,
glad you got it sorted!
Always nice as well when you know the tutorial is helping someone!
Hi
I have done an application using this tutorial.My application get open in hosted mode. when i ckick on search onFailure method of TeacherModel get called .this happen becoz in TeacherServiceImpl class
PupilCollection<..> collection = (PupilCollection<..>) ContextUtil.getContext().getBean("pupilCollection");
I am facing some problem.
I am not getting any exception on this line. but when debug an application control return back to teachermodel class.
Thanks in advance.
Hi there,
To try and spot your error you could download the source code:
http://eggsylife.blogspot.com/2008/05/source-code-available.html
Or alternatively post your code to a download site and provide me a link to it and I dont mind checking it over?
You can contact me on Twitter if you have an account:
http://eggsylife.blogspot.com/2009/02/twitter.html
Hi
I have done an application using this tutorial.
now I am getting this exception
[WARN] StandardContext[]Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List com.company.client.rpc.TeacherService.getPupils(java.lang.Integer)' threw an unexpected exception: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:360)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:546)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:164)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at com.google.gwt.dev.shell.GWTShellServlet.service(GWTShellServlet.java:289)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
at com.company.server.gwt.TeacherServiceImpl.getPupils(TeacherServiceImpl.java:40)
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 com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:164)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at com.google.gwt.dev.shell.GWTShellServlet.service(GWTShellServlet.java:289)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.springframework.context.ApplicationContext
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at com.company.server.gwt.TeacherServiceImpl.getPupils(TeacherServiceImpl.java:40)
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 com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:164)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at com.google.gwt.dev.shell.GWTShellServlet.service(GWTShellServlet.java:289)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Unknown Source)
HI eggsy84 ,
As you told me to share my application I have shared it at following link :
http://www.4shared.com/file/89743457/9ad2cbf/TheProject.html
Please find the same.
Thanks in advanced.
Hi there,
To the person experience the problem with the no class def found error. I have answered this query previously in this set of comments. Please see above.
Essentially it is because you are included server side code on your client side.
Your server side code should be under a package named client.
Hi
I shall take a look over your application and get back to you today.
Eggsy
Hi there,
I have checked through your project.
There were a couple of problems, mainly caused by incompatability issues.
The tutorial is quite dated now and was created against GWT 1.4 and Earlier versions of Spring but I notice you are using later versions of Spring and GWT.
Firstly just check your JDBC URL in your applicationContext there seems to be two '>'
Your versions of Spring were the latest versions and not compatible with the way I had done the app context so I have replaced them with the old versions from myt test project.
Also you need to add the Spring XSD files to your src directory.
GWT 1.5 works slightly different not when accessing RPC services and your code needs changing.
To help I have made the changes to your code and you can download it at:
http://www.mediafire.com/?sharekey=ea73870577485e6c41446e35a78dc463e04e75f6e8ebb871
But you'll need to edit the GWT compile and launch scripts again to point at your GWT paths as well as your applicationContext changes to point at your database URL/driver etc.
Make note of the difference in the client RPC interfaces TeacherService and for more information on the GWT 1.5 changes you can read a later blog post here:
http://eggsylife.blogspot.com/2008/11/hibernate-spring-and-gwt-for-gwt-15.html
Hi,
I have done modification the GWT compile and launch scripts , applicationContext But still I am getting same error.
[WARN] StandardContext[]Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List com.company.client.rpc.TeacherService.getPupils(java.lang.Integer)' threw an unexpected exception: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:360)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:546)
Hi,
Did you download the project and take a look at the differences?
They key points are the Spring Jars I have used. They are the older versions.
You can download the modified, working project at:
http://www.mediafire.com/?sharekey=ea73870577485e6c41446e35a78dc463e04e75f6
Hi,
I had downloaded the project from spacified link.
did the modification whatever u told me.
still I am getting same exception.
Now I have developed an application using gwt-windows-1.4.60 still I am getting same exception.
StandardContext[]Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List com.company.client.rpc.TeacherService.getPupils(java.lang.Integer)' threw an unexpected exception: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:361)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:547)
Hi
I have developed an application using using gwt-windows-1.4.60 as u told me.
but still I am getting an exception
StandardContext[]Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List com.company.client.rpc.TeacherService.getPupils(java.lang.Integer)' threw an unexpected exception: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:361)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:547)
I have shear an application created by using gwt-windows-1.4.60
at following link
http://www.4shared.com/file/90827680/89a58650/_2__TheProject.html?dirPwdVerified=98c1b523
Hi,
I've downloaded your source code and modified the MyApplication-compile to point to my jars. How do I run the application? I couldn't execute MyApplication-shell like I can with the sample GWT projects. I've opened the project in eclipse (I'm using myeclipse 6.6 with GWT 1.6 plugin) and when I click on the icon "GWT compile project" I get an error that says this is not a GWT project. Thanks for your help.
Hi there,
Unfortunately I haven't tested this with myeclipse and a GWT plugin.
Usually in Eclipse you just run it as a normal Java application. If you have setup the application.launch file correctly Eclipse should just pick it up and allow you to run it.
Eggsy
Hi Anonymous,
I think I may have the solution for your problem. In fact, it is a classpath problem mentioned before by Eggsy. Something is missing in the MyApplication-shell.bat. In there you find something like:
java -XstartOnFirstThread -cp "$APPDIR/WEB-INF/src:$APPDIR/WEB-INF/classes:/Users/james/Software/gwt-mac-1.4.61/gwt-user.jar:/Users/james/Software/gwt-mac-1.4.61/gwt-dev-mac.jar" com.google.gwt.dev.GWTShell -out "$APPDIR/www" "$@" com.company.MyApplication/MyApplication.html;
But, where is the reference for all the libs needed? You must have to add to the "-cp" option something like this :
$what-ever-path/spring-webmvc.jar
and so on for every lib needed.
Hope this helps :)
By the way, nice work Eggsy done here with this tutorial.
Hi Bruno,
Thank you for the reply and the help given to the previous commentators.
Also thank you for your comments regarding the tutorial as a whole.
Hello,
I have developed this application "TheProject" and it is working great.Futher for the purpose of validation I have developed another gwt application "Validation" for validation purpose.Now, I want to convert Validation application to a jar file and use it in my TheProject. Please help me and let me know how can I convert a GWT application to a jar file? and utilize it in my Project(Integrated application of gwt+spring+hibernate)?
Waiting for your reply...
Thank u
Hi there,
I have done this in the past and when you know how its relatively easy.
I'm quite busy at the moment but if you give me a few days I'll post a tutorial on the blog.
Hello,
Whenever u get time please work upon my problem and let me know the solution to it...
As posted earlier the problem is -
I want to convert Validation application(developed in gwt) to a jar file and use it in my TheProject. Please help me and let me know how can I convert a GWT application to a jar file? and utilize it in my TheProject(Integrated application of gwt+spring+hibernate developed using ur tutorial)?
Waiting for reply...
Thanks
Hi there,
Can u help me by providing the documentation or exact flow of this project. Also, the class diagram or UML of the project.
Thanks.
Hi there,
In terms of the tutorial theres not much really to model it is quite basic.
The modelling of the Persistent classes is self explanatory 1 Teacher has many students is pretty much as complicated as its gets ;)
In terms of the client server communication GWT themselves have a very useful model that they call their RPC plumbing diagram.
It can be seen here:
http://code.google.com/webtoolkit/doc/1.6/DevGuideServerCommunication.html#DevGuidePlumbingDiagram
You'll then be able to see how my classes map to it.
Post a Comment