This question is similar to this one, but that did not solve my problem.
I have a very simple Google AppEngine / Java application. It has been running since 2011, and does not use maven or other fancy stuff that I don't think I need. Recently, I added Cloud Endpoints to this application. I did not use generated endpoint-libs
, because I did not seem to need that, and everything works fine without it.
The application has had a frontend and a backend for some time. I am now trying to convert these to modules: The frontend will become the default module, and the backend will become another module.
The structure of my old project is like this:
project
|- src
| |- ... Java source files ...
|
|- war
| |- WEB-INF
| | |- appengine.xml
| | |- backends.xml
| | |- cron.xml
| | |- web.xml
I implemented cloud endpoints by providing Java classes with the right annotations. No fancy maven generating magic.
I understand that I need to create a directory for each module, like this:
project
|- default
| |- WEB-INF
| | |- appengine.xml
| | |- cron.xml
| | |- web.xml
|
|- module
| |- WEB-INF
| | |- appengine.xml
| | |- web.xml
|
|- META-INF
| |- appengine-application.xml
| |- application.xml
My questions are:
- Where should I put the
src
directory? - Should I declare my cloud endpoint classes in
default/WEB-INF/web.xml
? - Can each module have its own
WEB-INF/cron.xml
?
If it seems like I don't know what I am doing, that is probably right, but I don't want to have to put everything in a maven pom-file, write gradle scripts etcetera, and focus on the actual application instead. It's probably because I grew up with vi and emacs, in a time when we wrote code ourselves. ;)
Update:
I put the src directory under project
at the same level as default
and module
. The compiled Java classes appear under default/WEB-INF/classes
, which suggests that I did something right. GAE generates a *.api
file in default/WEB-INF
, which I did not see before when not using modules.
Locally, I can see my cloud endpoints APIs, and I can use them. When I deploy to AppEngine, and try to use the API explorer, I get an exception:
/_ah/spi/BackendService.getApiConfigs java.lang.NullPointerException at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:100) at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:71) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
etcetera...
I did add OAuth2 credentials and set them in my cloud endpoint configuration.
I could not find the code for SystemServiceServlet
, but my guess would be that it cannot find my API classes (which are configured in default/WEB-INF/web.xml
).
Another update:
I learned that AppEngine modules require an enterprise archive (ear) structure, and deploying like a simple GAE application is not going to work. There is no 'single press of a button' deployment. I followed the instructions in Programming Google App Engine with Java and ended up with a bunch of Eclipse projects. It is rather enterprisey, but I can get it to throw the same exception as the simple version I deployed earlier. I wonder if I made any progress at all.
Eventually, I followed the instructions given in Programming Google App Engine with Java (chapter 5) closely, and gradually added my old code. This worked, and I did not get the null-pointer exception any more (don't know what caused it).
Some points to be aware of:
-Ddatastore.backing_store=/C:/wherever/local_db.bin
The directory structure of my project now looks like this:
Most of this was generated by following the instructions in the aforementioned book.
I hope this will help others struggling with making their AppEngine projects modular.