Lesson Learned: Using an Apache Derby Embedded database with Google Web Toolkit
Apache Derby can be integrated with Google Web Toolkit. It requires, however, a few tricks. As it wasn’t all that straight forward, and included some time-consuming hunting-around on the Internet, I thought I would publish the troubles ( java.lang.ClassNotFoundException, java.lang.NoClassDefFoundError: java.io.FileOutputStream, and java.lang.NoSuchMethodError: org.mortbay.thread.Timeout.(Ljava/lang/Object;)V)) and answers all in once place. I hope it helps!
The Scenario
I am constructing a web-based application using Google Web Toolkit (for use on my workstation, and not hosted by Google). As I am storing and manipulating large amounts of data I decided that a relational database is the best technology for storing data. As technology I picked Apache Derby (embedded).
The Software Versions
The specific software versions I am using are:
Development Environment: Eclipse Helios (3.6) Service Release 2,
Apache Derby: 10.8.1.2,
Google Web Toolkit 2.3.0
Issues
You will already encounter the explained issues if you are creating a new Google Web Application project, generate the “GWT sample code”, and modify the class GreetingServiceImpl.java to do nothing more than opening a database connection to an embedded Derby database.
The application will throw this exception when a database connection is opened.
java.lang.ClassNotFoundException: org.apache.derby.jdbc.EmbeddedDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:176)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at testdb.server.GreetingServiceImpl.greetServer(GreetingServiceImpl.java:23)
Issue #1 / Fix #1: Adding dery.jar to the project's build-path
…
Explanation
This is probably one of the more obvious exceptions. You need to add the jar file containing the embedded database code as well as JDBC driver to the application’s compile- and run-time classpaths.
Fix
Two things could have gone wrong here:
You may have forgotten to add the file derby.jar to the build path of the project.
Issue #1 / Fix #2: Adding dery.jar to war/WEB-INF/lib/
In addition, though, you need to add the file derby.jar to the war/WEB-INF/lib/ directory.
Issue #2: java.lang.NoClassDefFoundError: java.io.FileOutputStream is a restricted class. Please see the Google App Engine developer’s guide for more details.
Sympton
This application throws this application when the application tries to open a connection.
Caused by: java.lang.NoClassDefFoundError: java.io.FileOutputStream is a restricted class. Please see the Google App Engine developer’s guide for more details.
at com.google.appengine.tools.development.agent.run…
Explanation
The GWT application runs in a sandbox, and simply does not allow particular accesses, such as using java.io.FileoutputStream into the local file-system. For a more complete picture please refer to “Google App Engine – The Java Servlet Engine: The Sandbox”.
Disabling Google App Engine Restrictions (Step 1)Disabling Google App Engine Restrictions (Step 2)
Fix
The fix is simple as well. Just disable the Google App Engine support for your application. Do this by right-clicking your Google Web Project, then select Properties > Google > App Engine.
This one is one of the more obvious ones. Anyway, if you run into it you probably have only added the jar file, containing the derby embedded JDBC driver, to your Eclipse build-path only.
Issue #3: Exception in thread “main” java.lang.NoSuchMethodError: org.mortbay.thread.Timeout.(Ljava/lang/Object;)V
Sympton
Finally, I received the exception above. This already occurs at the startup of the Google Application Engine.
Exception in thread “main” java.lang.NoSuchMethodError: org.mortbay.thread.Timeout.(Ljava/lang/Object;)V
at org.mortbay.io.nio.SelectorManager$SelectSet.<init>(SelectorManager.java:306)
at org.mortbay.io.nio.SelectorManager.doStart(SelectorManager.java:223)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at org.mortbay.jetty.nio.SelectChannelConnector.doStart(SelectChannelConnector.java:303)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at org.mortbay.jetty.Server.doStart(Server.java:233)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at com.google.gwt.dev.shell.jetty.JettyLauncher.start(JettyLauncher.java:667)
at com.google.gwt.dev.DevMode.doStartUpServer(DevMode.java:500)
at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:1055)
at com.google.gwt.dev.DevModeBase.run(DevModeBase.java:804)
at com.google.gwt.dev.DevMode.main(DevMode.java:309)
Also here, the fix is easy. Open your project’s build path and go to the “Order and Export” tab: Right-click project > Properties > Java Build Path > Order and Export tab.
Next move the GWT SDK library, at least, above the Google App Engine libraries. Then confirm it by selecting OK. It will make it work.
Finally, you will be able to start your Google Web Toolkit application, using an embedded Apache Derby database.
Thank! It helps me.
I am glad it helped. Thank you for the feedback!
Michael
Thaaaaaaaaaaanks, I experienced the issue #1 and couldn’t find the solution !
Great. I am glad it was of help!
Cheers,
Michael
Damn, it was haunting me for an entire hour, till i found your blog. I forgot to add the jars to the
In addition, though, you need to add the file derby.jar to the war/WEB-INF/lib/ directory.
WEB-INF directory >.<.
Much appreciated!
Welcome 🙂