If you're about to build a website running on Google AppEngine Java, with a backend using JDO entities and a fronted primarily on Google Web Toolkit, you might find the following tips handy. This is a summary of hurdles I faced (and crossed!) while trying to set things up.
First, the technology stack I will be talking about:
- Google AppEngine Java SDK 1.7.4
- JDO persistence (datanucleus-apppengine v2.1.1, datanucleus-api-jdo-3.1.1)
- RequestFactory 2.5.0
- Gin 2.0
- Guice 3.0 (With guice-servlet)
- GWT 2.5.0
- GWT Editor framework
Now, the tips. Each of these took me considerable time to figure out. Wherever possible, I've tried to link through to the sites/suggestions that got me through.
- Resolving ClassPath issues (ClassNotFoundException, NoSuchMethodException, No implementation for ... was bound)
- By and large, the most common problem you may run into, especially if you're managing dependencies within your IDE(E.g. Eclipse), is ClassPath errors.
There are plenty of sites explaining the difference between all of these and why they happen. But here's a site that helped me troubleshoot this on AppEngine dev mode:
The beauty about his approach is that he uses a "Listener" that can be added to your web.xml, and automatically run before any request. - Also, for some libraries, order import matters. E.g. GuiceInjectorBindings
- By and large, the most common problem you may run into, especially if you're managing dependencies within your IDE(E.g. Eclipse), is ClassPath errors.
- Setting up JDO
- AppEngine Documentation is pretty good on the basics of JDO. However, the documentation is misleading on Un-owned relationships and Many-to-Many relationships in DataNucleus v2- it suggests using List<Key> or Set<Key>. The DataNucleus API, on the other hand, will conveniently handle your list of objects. If you're using a Many-to-Many relationship, use Set<MyObj>, or make sure you specify an @Order annotation on your column. (List<MyObj> didn't work for me, so I failed back to using a Set, and having an attribute for client-side ordering)
- Request Factory, and GWT Editor Framework
- If you followed the Getting Started with RequestFactory guide, as-is and are closing your EntityManager or PersistenceManager for every single method(such as persist() or remove()), then you're not following the OpenSessionInView (Session-per-request) pattern. GWT Editor framework will not be able to handle your "related entities" in this case.
Your options are: 1) use Guice for creating a Request-scoped PersistenceManager, or 2) switch away from JDO, and move to Objectify or Twig or some other interface that already takes care of a lot of persistence logic for you.
- If you followed the Getting Started with RequestFactory guide, as-is and are closing your EntityManager or PersistenceManager for every single method(such as persist() or remove()), then you're not following the OpenSessionInView (Session-per-request) pattern. GWT Editor framework will not be able to handle your "related entities" in this case.