Recently more people seem to use FirstSpirits capabilities to extend functionality with custom services and custom components.And I'm always happy to support this.
One common pitfall seems to be the communication between a custom input component (aka Gadget) and a service, which fails with a ServiceNotFoundException caused by a ClassNotFoundException.
This is the common failure trace:
de.espirit.firstspirit.access.ServiceNotFoundException: Service '<custom service interface name>' not found
at de.espirit.firstspirit.server.io.AbstractServiceLocator.getService(AbstractServiceLocator.java:52)
at de.espirit.firstspirit.server.io.AbstractServiceLocator.getService(AbstractServiceLocator.java:92)
at de.espirit.firstspirit.server.io.AbstractServerConnection.getService(AbstractServerConnection.java:553)
at de.espirit.firstspirit.client.io.WebConnection.getService(WebConnection.java:254)
at de.espirit.firstspirit.agency.ServicesBrokerImpl.getService(ServicesBrokerImpl.java:26)
<part from custom code>
<long part from FirstSpirit code>
Caused by: java.lang.IllegalStateException: java.lang.ClassNotFoundException: <custom service interface name>
at de.espirit.firstspirit.server.io.RemoteServiceLocator.createService(RemoteServiceLocator.java:93)
at de.espirit.firstspirit.server.io.AbstractServiceLocator.getService(AbstractServiceLocator.java:50)
... XX more
Caused by: java.lang.ClassNotFoundException: <custom service interface name>
<potentially long part from web container code>
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at de.espirit.firstspirit.server.io.RemoteServiceLocator.createService(RemoteServiceLocator.java:50)
... ZZ more
The cause is that the class is simply not known within the scope of the web environment.
To fix this, first your module needs to define the web-app block in the descriptor (module.xml😞
<module>
...
<components>
...
<web-app>
<name>...</name>
<displayname>...</displayname>
<description>...</description>
<web-xml>web.xml</web-xml>
<web-resources>
<resource>lib/your.jar</resource>
</web-resources>
</web-app>
...
</components>
...
</module>
Relevant are the web-resources line which must reference your JAR file and the web-xml line.
The web.xml file itself may have minimal content:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<display-name>...</display-name>
<description>...</description>
</web-app>
The structure of your FSM file should then (at least) look like this:
+ lib
- your.jar
+ META-INF
- MANIFEST.MF
- module.xml
- web.xml
The next step is to add and deploy the web application (at least into the Preview scope):
After these steps, the ClassNotFoundException is history.
[tested with upcoming 5.1 release - release 5.0 may be less restrictive when "Internal Jetty" is used as web server]