TwinTechs

Dream, Create, Deliver…

Java Application Tier Framework Tailored For LiveCycle Data Services Projects

September 13th, 2009 Written by: Michael Korthuis · J2EE, Java, LiveCycle

With the proliferation of LiveCycle Data Services, it surprises me that there has not been more attention paid to the creation of a Java framework for standard three tiered implementations of LCDS. Of course, in a perfect world, the application tier development should be completely agnostic to your service and UI tiers. However, long term, you can save yourself a lot of headaches if you think about the consequences of an application’s service tier and UI tier architectures. The most obvious case of this is how assemblers execute updates for all clients

As far as I know, the only application tier framework option available that is tailored to LCDS is the Adobe LCDS Hibernate plug-in. However, when using this framework, it quickly becomes apparent that it is not a good solution for enterprise level applications. Reason: the Hibernate plug-in makes the application tier little more than a transportation layer. Using the Hibernate plugin-in, one is effectively creating a client server application. This can be troublesome on many fronts, such as:

  • You can’t always assume the only consumer of the application tier is going to be a Flex client. Web Services and a “classic” or “ajaxy” HTML front end may also need to be implemented.
  • No business logic can be implemented on the middle tier and consumed across clients. All business logic must be implemented in the database and/or client.
  • Security becomes very complicated.
  • Hibernate is not good for bulk data transfers (example: reporting). It specializes in transactional operations.

Due to the lack of options available and lack of development time to come up with a clean architecture, my experience has been that the middle tier architectures of most LCDS applications are not well thought out. LCDS applications generally result in some sort of standard DAO and entity implementation (probably Hibernate) coupled with bloated mapping classes to handle all entity to value object creation. Business logic tends to be sprinkled in between the mappings and is not abstracted at all. This type of architecture (or lack thereof) might work well during the prototyping phase. However, it quickly becomes unwieldy and error prone.

To resolve the architectural problems I’ve seen, I came up with a personal framework that I use for LCDS application development. It covers the entire application tier from DAO’s and Entity Beans to the assemblers and value objects that are being passed back to the UI.

The goal of the framework was to speed up development, follow generic patterns, minimize bugs and ensure a flexible enough solution to fit any type of application. Ease of use was important but not the most critical requirement. I find that each application I write is slightly different and the framework needs to be generalized a little more for each project needs. The framework is meant to solve the common problems one faces and not every problem.

To get a high level overview of the framework and its usage, check out the document posted here.

Next Steps: The framework is still evolving, and there are some features I will likely need to add for future projects. Some big extensions that may need to be added are:

  • Utilization of the java scripting engine in 1.6 for writing business rules in JavaScript. This allows easy customization of the business rules without requiring a system restart.
  • Creation of an ActionScript rules engine that can leverage the same JavaScript rules in the application tier. This saves writing validation scripts on both the client and server side (Think email address).
  • Further streamlining of some of the mapping files, and removing full package names where possible by keying off of directory locations instead of mapping files.
  • Creation of a Web Service DAO Factory and a JDBC DAO Factory.
  • Creation of a generic web service client.
  • Usage of Session and Entity Beans in EJB3.

If you are at all interested in the framework, feel free to shoot me an email at michael.korthuis@twintechs.com and we can talk about it further.

→ No CommentsTags:

Twin Tech Guru Gus Holcomb Speaks at InsideMobile

August 2nd, 2009 Written by: julie.colwell · Android, Flash Catalyst, J2EE, Java, LiveCycle, Mobile Devices, News, RIA

Twin Technologies’ Gus Holcomb spoke at the first ever InsideRIA conference this week in San Francisco.  Java engineers interested in learning how to program iPhone apps came to hear his presentation.  

Gus says people are often intimidated by programming for the iPhone  because the language is weird and while there are a number of tools you can use, selecting the right one for what you want to do can be tricky.  Gus talked about what makes the iPhone  language different,  the language features you need to know about.  By using the right tools, what might initially look daunting, gets a lot easier when you look at how to link objects together.  

Gus showed two code examples… enough to get people to get out and start working on it, so they knew enough to start getting their programs out.   Since the audience was already fluent in Java, Gus used Java to prove concepts that appear tricky on the surface so he could relate them to familiar material.  

Look for Gus’ lunch and learn on iPhone development coming this fall!

→ No CommentsTags: ····

How to Find What Function Is At a DLL Offset (without having debug symbols)

November 7th, 2008 Written by: Jesse Dailey · J2EE, LiveCycle

How to Find What Function Is At a DLL Offset (without having debug symbols):

This applies to all applications, but this specific example comes from Adobe LiveCycle.  The PDF Generator was crashing mysteriously, producing errors in the event log:

“Faulting application pdfgen.exe, version 1.0.0.1, faulting module ntdll.dll, version 5.2.3790.3959, fault address 0×0002eb5a”

This is a particularly annoying kind of error when its not in an application you control, since you don’t have any idea what 0×0002eb5a means without access to a build with debugging symbols.

To find out more, here’s what you need.

First you need a debugger.  The free option of choice for many people these days is OllyDbg (download here http://www.ollydbg.de/odbg110.zip)

It’s a simple applicaiton, so just extract it to a folder someplace and run it.

Once inside, File > Open, browse to the crashing dll, in this case, c:\windows\system32\ntdll.dll

It will ask if you want LOADLL.exe to load the dll for you, say Yes.

Once inside, note the starting offset.  It will vary based on the dll and the OS, but in my case the first address was 0×78001000, which means the base is at 0×78000000 (the trailing 1000 will be the same on all systems, its the first part you care about).

So, our application is crashing at offset 0×0002eb5a.  The reason its called an ‘offset’, is because it is ‘offset from the base’, so add 0×78000000 to 0×0002eb5a = 0×7802eb5a (Windows Calculator in Hex Mode can help you with this if your base is not an easy one like ours).

Scroll the debugging window to this address.

In OllyDbg, the beginning of each function is labeled with a $ sign.   The address we scrolled to should be in the middle of a function, so scroll up the start of the function (the first $ above it) and write down its starting address.  In this case, the function starts only a few bytes earlier, at 0×0002eb4e.

Open the menu: Debug > Call DLL Export.  On this window at the top there is a drop down labeled Export:, open this and scroll down to find the offset of the function you wrote down.

This should give you the textual name.  In my case, this name was ‘RtlLengthSid’, a quick google for this reveals it is a windows system call for computing the length of a security identifier.

From this, it was an easy leap to see that something in the LiveCycle environment was working with a user account it didn’t support.  This, ultimately, was enough for us to diagnose and fix our problem (by starting WebLogic’s NodeManager as Administrator, rather than Local System, the installation’s default).

→ No CommentsTags: ··

Installation and Configuration of LocalSolr.

May 18th, 2008 Written by: davidm · J2EE, Java

A client of mine asked me to investigate localsolr which= extends Apache Solr server with the ability to perform text searches filtered on geographical distance from a given point specified by latitude and longitude. Here are the steps that I followed:

Download the Software

1. Downland Ant
2. Download Tomcat
3. Download LocalLucene
4. Download LocalSolr
5. Download Solr-1.3-dev, via svn, to get the source code

svn checkout http://svn.apache.org/repos/asf/lucene/solr/trunk apache-solr-1.3.dev

6. Uncompress all of the software packages.

Create Environment Variables

1. In Unix variants, update your .bash_login script to include the following. Of course, you’ll need to set the variables correctly according to where you uncompressed the software. And don’t forget to source the .bash_login file after you have changed it.

export SUPPORT_DIR=/home/medined/support
export LOCAL_LUCENE_HOME=$SUPPORT_DIR/locallucene-r1.5
export LOCAL_SOLR_HOME=$SUPPORT_DIR/localsolr-r1.5
export SOLR_HOME=$SUPPORT_DIR/apache-solr-1.3-dev
export SOLR_CONFIG=/home/medined/.solr
export TOMCAT_HOME=$SUPPORT_DIR/apache-tomcat-6.0.16

export JAVA_OPTS=”$JAVA_OPTS -Dsolr.solr.home=$SOLR_CONFIG”

Create Apache Solr War

1. cd $SOLR_HOME
2. ant dist

Configure Local Solr

1. cp -R $SOLR_HOME/example/solr $SOLR_CONFIG
2. cp $SOLR_HOME/libs/solr/apache-solr-1.3-dev.war $TOMCAT_HOME/webapps/solr.war mkdir $SOLR_CONFIG/lib
3. cp $LOCAL_LUCENE_HOME/dist/locallucene.jar $SOLR_CONFIG/lib
4. cp $LOCAL_SOLR_HOME/dist/localsolr.jar $SOLR_CONFIG/lib
5. cp $LOCAL_LUCENE_HOME/lib/gt2-referencing-2.3.1.jar $SOLR_CONFIG/lib
6. cp $LOCAL_LUCENE_HOME/lib/geoapi-nogenerics-2.1-M2.jar $SOLR_CONFIG/lib
7. cp $LOCAL_LUCENE_HOME/lib/jsr108-0.01.jar $SOLR_CONFIG/lib
8. Add the following to the end of $SOLR_CONFIG/conf/solrconfig.xml (just before the closing CONFIG tag:

<updateRequestProcessor>
<factory name=”standard” class=”solr.ChainedUpdateProcessorFactory” default=”true”>
<chain class=”com.pjaol.search.solr.update.LocalUpdateProcessorFactory”>
<str name=”latField”>lat</str>
<str name=”lngField”>lng</str>
<int name=”startTier”>9</int>
<int name=”endTier”>17</int>
</chain>
<chain class=”solr.LogUpdateProcessorFactory” >
<!– <int name=”maxNumToLog”>100</int> –>
</chain>
<chain class=”solr.RunUpdateProcessorFactory” />
</factory>
</updateRequestProcessor>

<requestHandler name=”geo” class=”com.pjaol.search.solr.LocalSolrRequestHandler”>
<!– Custom latitude longitude fields, below are the defaults if not otherwise
specified –>
<str name=”latField”>lat</str>
<str name=”lngField”>lng</str>
</requestHandler>

9. Add the following to the fields tag of $SOLR_CONFIG/conf/schema.xml

<field name=”lat” type=”sdouble” indexed=”true” stored=”true”/>
<field name=”lng” type=”sdouble” indexed=”true” stored=”true”/>
<dynamicField name=”_local*” type=”sdouble” indexed=”true” stored=”true”/>

Controlling Tomcat

* $TOMCAT_HOME/bin/startup.sh – this command starts Tomcat.
* tail -f $TOMCAT_HOME/logs/catalina.out – this command lets you watch Tomcat’s output log.
* $TOMCAT_HOME/bin/shutdown.sh – this command stops Tomcat.

If you’re lucky enough to be using Unix then combine the first two commands onto one line:

$TOMCAT_HOME/bin/startup.sh; tail -f $TOMCAT_HOME/logs/catalina.out

Importing Data Into Apache Solr

When LocalSolr is deployed into Tomcat, the default port is 8080. However, the Apache Solr import tools use a different hardcoded port. This causes me a but of angst until I realized that I could easily copy the SimplePostTool and change the port. So copy $SOLR_HOME/src/java/org/apache/solr/util/SimplePostTool.java, change the port specified on line 46 (see below) and compile it.

public static final String DEFAULT_POST_URL = “http://localhost:8080/solr/update”;

I create a data file that looked like this

<add>
<doc>
<field name=”id”>01</field>
<field name=”name”>HOUSE01</field>
<field name=”lat”>39.36</field>
<field name=”lng”>-77.4027</field>
<field name=”text”>zxy</field>
</doc>
<doc>
<field name=”id”>02</field>
<field name=”name”>HOUSE02</field>
<field name=”lat”>38.36</field>
<field name=”lng”>-77.4027</field>
<field name=”text”>zxy</field>
</doc>
</add>

Then I simply executed the SimplePostTool program passing it the name of the data file as the program argument.

Apache Solr Admin Screen

With Tomcat running, you should be able to connect with http://localhost:8080/solr/admin/

Local Solr GIS Query

With Tomcat running, you should be able to execute a GIS-based query by connecting to http://localhost:8080/solr/select?&qt=geo&lat=38.8700&long=-77.4027&q=zxy&radius=1. The q=zxy tells Apache Solr to return all documents. The lat and long parameters indicate the center of the circle to search using decimal degrees. While the radius parameter indicates the radius, in miles, of the circle.

Good Luck!

→ 2 CommentsTags: ·

Using Struts v1.x to display a select list with html:optionCollection tag

April 30th, 2008 Written by: davidm · J2EE, Java

Recently I was using Struts v1.x and I needed to display a select list. The information about how to use the html:optionsCollection tag was sketchy. I was able to get the tag working this way:

On the JSP page, I added this inside the html:form tag: <html:select property=”selectedEquipment”> <html:optionsCollection property=”equipment” label=”name” value=”id”/> </html:select>

Then I create a Java class called SelectOption like this: package com.codebits.struts;

public class SelectOption {

String id;

String name;

SelectOption() {

}

SelectOption(final String _id, final String _name) { setId(_id); setName(_name); }

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

Next I created an ActionForm bean:

package com.codebits.struts;

public class AddForm extends ActionForm {

private Integer selectedEquipment = null;

private List equipment = new ArrayList();

public Integer getSelectedEquipment() { return selectedEquipment; }

public void setSelectedEquipment(Integer selectedEquipment) { this.selectedEquipment = selectedEquipment; }

public List getEquipment() {

return equipment;

}

public void addEquipment(final String equipmentId, final String

emtEquipmentId) {

this.equipment.add(new SelectOption(equipmentId, emtEquipmentId)); }

public void setEquipment(List equipment) { this.equipment = equipment; }

}

And finally, in my action class, I prepopulated the ActionForm bean:

AddForm addForm = (AddForm)form;

addForm.addEquipment(“1″, “AAA”);

addForm.addEquipment(“2″, “BBBB”);

Originally posted here.

→ No CommentsTags: ·