JMS Messages as DataSource

Is it possible to use a JMS topic as a DataSource? I’ve read client/server integration techniques in the documentation and reviewed some examples on Showcase; I’m still not sure how/if this can be accomplished.

I’m using SmartGWT 2.4 and FireFox 3.6; this is what I have thus far:

client code:
public class DoThis{
public void onModuleLoad(){
ListGrid listGrid = new ListGrid();
listGrid.setWidth100();
listGrid.setHeight(450);
DataSource ds = DataSource.get(“eventDataDMI”);
listGrid.setCanEdit(false);
listGrid.setDataSource(ds);
listGrid.fetchData();

}
)

custom DataSource: eventDataDMI.ds.xml

<DataSource
ID=“eventDataDMI”
serverType=“generic”
dataFormat=“iscServer”
serverConstructor=“com.example.server.MessageDataDMI”

clientOnly="false" &gt;
   
   &lt;fields&gt;
  &lt;field name="id"    title="Event ID"     type="sequence"  primaryKey="true"  	align="left"	 hidden="false" 	length="70"/&gt;	
  &lt;field name="eventDateTime"  title="Date - Time"  type="text"       length="120"/&gt;			
  &lt;field name="eventText" 	   title="Event Text"   type="text"       length="300"/&gt;
  &lt;/fields&gt;

  &lt;operationBindings&gt;
    &lt;operationBinding operationType="fetch" &gt;
        &lt;serverObject className="com.example.server.MessageDataDMI" methodName="executeFetch" /&gt;
    &lt;/operationBinding&gt;     
&lt;/operationBindings&gt;  

</DataSource>

server code:

public class MessageDataDMI extends BasicDataSource {

private static final long serialVersionUID = 1L;
EventData eventData = new EventData();

public DSResponse executeFetch(DSRequest req) throws Exception {

  List records = fetchRecords(req.getCriteria());     
  return new DSResponse(records);

}

public List fetchRecords (Map criteria) {
eventData.subscribeToMessages();
return eventData.getList();

}

}

server sample code to subscribe to JMS Topic:

public class EventData {
Subscription sub = Subscription .Factory.getInstance();
static List list = new ArrayList();
static List getList(){
return list;
}

public List subscribeToMessages() {
SubscriptionCallback<Event> subCallBack = new
SubscriptionCallback<Event>()
public void onReceive(Event theEvent)
{
long id;
Date eventDateTime;
String eventText;

          Map map = new HashMap();
          map.put("id", id = theEvent.getID());
          map.put("eventDateTime", eventDateTime = 
                       theEvent.getTimestamp());
          map.put("eventText", eventText = theEvent.getMessage());
          list.add(map);               
      }     
  };          
  sub.subscribe(Event.class, subCallBack);
  return list;

}
}

web.xml:
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE web-app
PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”
“http://java.sun.com/dtd/web-app_2_3.dtd”>

<web-app>

<!–
The DataSourceLoader servlet returns Javascript representations of the
dataSources whose ID’s are passed to it - it is an alternative to
using the <loadDS> JSP tag
–>
<servlet>
<servlet-name>DataSourceLoader</servlet-name>
<servlet-class>com.isomorphic.servlet.DataSourceLoader</servlet-class>
</servlet>

  &lt;!-- DataSourceLoader requests --&gt;
  &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;DataSourceLoader&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/dothis/sc/DataSourceLoader&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;

<servlet>
<servlet-name>IDACall</servlet-name>
<servlet-class>com.isomorphic.servlet.IDACall</servlet-class>
</servlet>

<!-- RPCManager uses this URL by default for Built-in DataSource operations –>
<servlet-mapping>
<servlet-name>IDACall</servlet-name>
<url-pattern>/dothis/sc/IDACall/*</url-pattern>
</servlet-mapping>

<!-- Default page to serve –>
<welcome-file-list>
<welcome-file>DoThis.html</welcome-file>
</welcome-file-list>

</web-app>

Root html:

<!doctype html>

<html>
<head>
<meta http-equiv=“content-type” content=“text/html; charset=UTF-8”>
<title>Do This</title>
<link rel=“stylesheet” href=“DoThis.css”>
<script>
var isomorphicDir = “dothis/sc/”;
</script>
<script type=“text/javascript” language=“javascript”
src=“dothis/productdistribution.nocache.js”></script>

<script type=“text/javascript” language=“javascript”
src=“dothis/sc/DataSourceLoader?dataSource=eventDataDMI”></script>

</head>
<body>
<iframe src=“javascript:‘’” id=“__gwt_historyFrame” tabIndex=‘-1’
style=“position: absolute; width: 0; height: 0; border: 0”></iframe>
</body>
</html>

When new messages are published to this topic, the messages should be displayed to the bound ListGrid.
I’m not sure where to go from here.
Any help would be great!

Ran this setup; received a null pointer exception when I set the DataSource.

offending code:
listGrid.setDataSource(ds);

Error:
java.lang.NullPointerException: null
at com.smartgwt.client.widgets.grid.ListGrid.setDataSource(ListGrid.java:12572)

Any ideas?

See FAQ for a series of troubleshooting steps for a null DataSource.

Thank you for your speedy reply.

Went through the checklist in the FAQ. This checklist talks about DataSource.get() returning null; in my code, listGrid.setDataSource(ds) returned null. However, a double check is always good.

In server.properties, $webRoot/shared/ds points to the correct ds.xml; webroot has been auto detected via: webRoot: AUTODETECT

Before trying this, I worked through custom DataSource Showcase sample:
http://www.smartclient.com/smartgwtee/showcase/#simple_custom_ds

and documentation: Interface WriteCustomDataSource:
http://www.smartclient.com/smartgwtee/javadoc/com/smartgwt/client/docs/WriteCustomDataSource.html

To a newbie like me, everything appears good.

Have I missed something? Is it possible to use JMS messages as a Datasource in this way?

Thanks!

The FAQ is about your problem. Just keep going through the checklist - looks like you’ve checked 1 or 2 of the 6 or so possible problems so far.

Very Well, I’ll continue the checklist.

Checklist:
Make sure the <script src=> tag pointing to the DataSourceLoader servlet is placed after
the <script src=> for your GWT application (*.nocache.js).

In my config, Root .html conforms to this order.

Checklist:

Check the server-side log for errors such as malformed XML. If you see something about missing files, you have the wrong imports in your .gwt.xml file - do not import com.smartgwt.SmartGWT, import the Pro, Power or EE version instead (com.smartgwtee.SmartGwtEE, com.smartgwtpro.SmartGwtPro, or

com.smartgwtpower.SmartGwtPower).

In my module.gwt.xml file:
<inherits name=‘com.smartgwtee.SmartGwtEE’ />
Not seeing any malformed XML errors.

Checklist:
#Check that your server.properties setting for “project.datasources” matches the directory where you have placed your .ds.xml file

Confirmed this config in previous post.

Checklist:
#Make sure the DataSource ID you pass to DataSource.get() matches the file name (should be dataSourceId.ds.xml) and matches the ID attribute on the <DataSource> tag (note: attribute is “ID” not “id”). DataSource IDs are case sensitive, including the file name.
Confirmed in DataSource: eventDataDMI.ds.xml file attached to previous post.

Checklist:
#Make sure the DataSourceLoader servlet is actually present in web.xml, that the required
“Init” servlet is also present and that the <script src=> tag is pointing at the correct URL
for the DataSourceLoader servlet. The easiest way to check the latter is to use
Firebug’s NET panel.
My config:
I do have Firebug installed, but, have not experience using it; Went to the Net tab and expanded GetDataSourceLoader?datasource and saw datasource = eventDataDMI

DataSourceLoader servlet is present in the web.xml file.

Checklist is complete. What did I miss?

Thanks!

You just told use what you missed :). The Firebug “Net” panel has a tab that shows you the response from the DataSourceLoader servlet. If it’s a 404, the servlet is not at that URL. If its not a 404 but the response contains an exception or other error, there’s your problem.

Way Cool! Thanks for taking the time to help me develop troubleshooting skills/techniques! There are a lot of moving parts here! :slight_smile:

Now, for the response in the Response tab:
javax.servlet.ServletException: java.lang.ExceptionInInitializerError: Instantiation of class: com.example.server.MessageDataDMI threw an ExceptionInInitializerError - most likely cause is a failure to initialize the class (check your static initializers). Root cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘publisher’: Injection of autowired dependencies failed; org.springframework.beans.factory.BeanCreationException: Could not autowire method:the_errant_method …

The rest of the error points to a Root cause outside of the code we are investigating.

One last question, from the way I have written the client and server code here, is the Isomorphic and SmartGWT classes expecting messages on this JMS topic BEFORE this instantiation of this code? As it stands now, I’m instantiating this client/server code first, THEN firing up the code to publish messages to this topic.

Thanks!

That same error is reported in the server-side log, so that would have been an easier way to find out.

The only thing going on at DataSource loading time is finding out the field definitions for delivery to the client. No actual CRUD operations are being performed.