Feeds:
Posts
Comments

If you are looking to create a portlet that accesses a non-liferay database, follow these instructions. I am using the Liferay 6.0.x Tomcat bundle with the eclipse ide plugin to create a portlet that accesses a db2 database. The main lportal database is living in mysql.

My service.xml file looks like this:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE service-builder PUBLIC “-//Liferay//DTD Service Builder 6.0.0//EN” “http://www.liferay.com/dtd/liferay-service-builder_6_0_0.dtd”&gt;
<service-builder package-path=”com.aonhewitt.benit.gmc.services”>
<author>Rtbaird</author>
<namespace>mynamespace</namespace>
<entity name=”MailboxItem” local-service=”true” remote-service=”false” data-source=”zzzDataSource” table=”mailboxitem”>
<column name=”mailboxitemid” type=”String” primary=”true” />
<column name=”mailboxid” type=”String” />
<column name=”publicationdate” type=”Date” />
<column name=”docdesc” type=”String” />
<order by=”asc”>
<order-column name=”publicationdate” />
</order>
<finder name=”MailboxId” return-type=”Collection” >
<finder-column name=”mailboxid” />
</finder>
</entity>
</service-builder>

The key here is the data-source attribute on the entity. I will need to define this datasource in spring files. Once you run the service builder, take a look at the service.properties file generated in your source directory. You’ll see references to all the spring-configs files which includes an extension file listed at the end for WEB-INF/classes/META-INF/ext-spring.xml. This is where you will put your spring file overrides. You’ll need to define your data source here as well as override the hibernate session bean.

<bean>
<property name=”location”>
<value>/WEB-INF/jdbc.properties</value>
</property>
<property name=”placeholderPrefix” value=”${jdbc.” />
</bean>
<bean id=”zzzDataSource”>
<property name=”driverClassName” value=”${jdbc.xxx.driverClassName}” />
<property name=”url” value=”${jdbc.xxx.url}” />
<property name=”username” value=”${jdbc.xxx.username}” />
<property name=”password” value=”${jdbc.xxx.password}” />
</bean>
<bean id=”liferayHibernateSessionFactory” class=”com.liferay.portal.spring.hibernate.PortletHibernateConfiguration”>
<property name=”dataSource” ref=”zzzDataSource” />
</bean>

Here I’ve defined a property placeholder which allows you to specify the jdbc properties in a file called jdbc.properties. This file should be created in the WEB-INF directory and look like this. Notice “jdbc” was left off (since the property placeholder defined the prefix):

xxx.driverClassName=com.ibm.db2.jcc.DB2Driver
xxx.url=jdbc:db2:///SCHEMA
xxx.username=username
xxx.password=password
xxx.defaultAutoCommit=false

Now you’ve defined the datasource, defined the database connection properties, and overrode the hibernateSessionFactory to use this data source (main session factory definition is in the hibernate-spring.xml file).

So to recap:

  • service.xml defines your service and what datasource to use for a given entity/table
  • [run service builder]
  • service.properties defines your spring override file – you shouldn’t need to change this
  • ext-spring.xml (you need to create) defines the spring overrides including the hibernateSessionFactory, datasource bean, and property placeholder bean
  • jdbc.properties defines the database connection properties

After publishing my portlet to Tomcat, it is pulling data from an external DB2 database.  Notice I’ve said nothing about creating a datasource inside of Tomcat itself for this database connection.  As surprising as that is, it doesn’t seem to be needed.

If you need to capture SSL trace information when making an HTTPS call from your web application running under Websphere 7, add a jvm -D property for javax.net.debug with a value of ssl and any other additional tracing levels as defined in the link below. For example:

-Djavax.net.debug=ssl,handshake,data,trustmanager

Refer to this link:
JSSE Reference Guide

This will allow you to see trust store information, certificate chaining details and other information that should help you debug issues with making https calls from your server. If you are trying to connect to a web server that has a self-signed certificate, you’ll need the signer cert added to the \java\jre\lib\security\cacerts keystore within the Websphere install directory. Note – the default password for keystores is “changeit”.

Here’s an example of the output from the tracing. You can see the trace tells you the location of the cacerts file used for cert lookup:

[1/23/11 20:23:32:578 CST] 00000023 SystemOut O setting up default SSLSocketFactory
[1/23/11 20:23:32:578 CST] 00000023 SystemOut O class com.ibm.jsse2.SSLSocketFactoryImpl is loaded
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O Installed Providers =
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMJCE
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O BC
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMJSSE
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMJSSE2
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMJGSSProvider
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMCertPath
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMPKCS11Impl
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMCMSProvider
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMSPNEGO
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMSASL
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMXMLCRYPTO
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O IBMXMLEnc
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O Policy
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O keyStore is: C:\Program Files\IBM\SDP75\runtimes\base_v7\java\jre\lib\security\cacerts
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O keyStore type is: jks
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O keyStore provider is:
[1/23/11 20:23:32:593 CST] 00000023 SystemOut O init keystore
[1/23/11 20:23:32:640 CST] 00000023 SystemOut O init keymanager of type IbmX509
[1/23/11 20:23:32:640 CST] 00000023 SystemOut O trustStore is: C:\Program Files\IBM\SDP75\runtimes\base_v7\java\jre\lib\security\cacerts
[1/23/11 20:23:32:640 CST] 00000023 SystemOut O trustStore type is: jks
[1/23/11 20:23:32:640 CST] 00000023 SystemOut O trustStore provider is:
[1/23/11 20:23:32:640 CST] 00000023 SystemOut O init truststore
[1/23/11 20:23:32:656 CST] 00000023 SystemOut O adding as trusted cert:
[1/23/11 20:23:32:656 CST] 00000023 SystemOut O Subject: CN=Certum Trusted Network CA, OU=Certum Certification Authority, O=Unizeto Technologies S.A., C=PL
[1/23/11 20:23:32:656 CST] 00000023 SystemOut O Issuer: CN=Certum Trusted Network CA, OU=Certum Certification Authority, O=Unizeto Technologies S.A., C=PL
[1/23/11 20:23:32:656 CST] 00000023 SystemOut O Algorithm: RSA; Serial number: 0x444c0
[1/23/11 20:23:32:656 CST] 00000023 SystemOut O Valid from Wed Oct 22 12:07:37 GMT 2008 until Mon Dec 31 12:07:37 GMT 2029

Naperville Turkey Trot 2010

We ran the Turkey Trot in Naperville on Thanksgiving day. First time ever for any of us running a 5K. No training, no working out prior. Just get up at 7am and run. It was a little cold and wet, but wasn’t raining when we ran. I couldn’t believe how great the boys did. It just seemed so effortless for them, especially when afterwords they said it wasn’t that hard. I’d love to see them actually push themselves the whole race! Out of 105 kids in the 1-9 age group, Braden was 18th, Logan was 24th and Jake was 25th. There were 7000 people running total.

Results:

Braden 29:27
Bob 30:22
Logan 30:23
Jake 30:32
Tasha 30:32

I’ve received a couple questions regarding the overall process/steps to follow to migrate.  Hopefully this will help clarify the overall process one should follow to get your apps running on Websphere 7.0.

First, review this developerworks migration guide.  It covers most of what you’ll need to do.

I’ll supplement this with calling out the following steps specifically:

  1. If you’re using WSAD/RAD as your IDE, you’ll need to migrate your J2EE projects.  There is a migration guide within RAD 7.5.  Read it, make sure you understand it, and follow it.
  2. Understand what specifications are supported by WAS7. A big difference is JDK 1.6 for example.
  3. Read and understand the specs you are using.  If you have a basic web app, understand the servlet spec.  If you use EJBs, read the EJB spec.  JMS?  Same.  A basic understand of how a servlet or jsp works is not a replacement for understanding the entire specification.  There are many details that should be understood beyond the basics, if nothing else for educational purposes.  If you don’t understand the “rules”, it’s hard to play the game.
  4. Understand your application.  This refers to what pieces of the J2EE specification your application uses, and if you are doing anything in your application that isn’t supported by the specification(s).  I ran into this with creating threads to process work in parallel.  I’ve posted details below.  This will help you identify what areas of your application you need to change.  If you follow the specs, deploying is much easier.
  5. Understand your dependencies.  For example, if you rely on a specific version of some open source libraries, make sure they are supported by JDK 1.6.  Some libraries (bouncycastle for example) have different versions depending on the JDK you’re using.
  6. Redesign/code anything you need to change per the specs.  Rebuild your app using JDK 1.6.
  7. If you are using RAD, create and configure a local test server.  If you are not, download, install, and setup Websphere Developers Edition.
  8. Deploy your app to the server
  9. Thoroughly test every part of your application.  If your app is complex, the odds are good you’ll have missed something.  The only way to ensure it works is to run it.

One thing I ran into mentioned above was an issue related to creating our own threads to process work in parallel, or fire off background processes to load data the application uses.  The servlet spec prohibits applications from creating their own threads and accessing JNDI resources.  Websphere 6 (and prior) allows this.  Websphere 7 now enforces it, so some of our processes would fail because the threads performing work (JDBC calls for example) weren’t managed by websphere. Here’s the exception:

[3/22/10 10:18:51:968 CDT] 00000034 SystemOut     O javax.naming.ConfigurationException: A JNDI operation on a “java:” name cannot be completed because the server runtime is not able to associate the operation’s thread with any J2EE application component.  This condition can occur when the JNDI client using the “java:” name is not executed on the thread of a server application request.  Make sure that a J2EE application does not execute JNDI operations on “java:” names within static code blocks or in threads created by that J2EE application.  Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on “java:” names. [Root exception is javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".]

Websphere allows you to process parallel work by using it’s Asynchronous Beans facility.  To get our app to work, we created a work manager utility class to manage the threaded work within the container’s context.  Instead of calling Thread.start(), call MyWorkManager.start(<runnable>,).  This will submit the runnable work to the Websphere work manager for execution on a separate thread pool thread.  That work manager will need to be configured in the Websphere admin console.  Here’s the code for our utility class:
import javax.naming.InitialContext;
import com.ibm.websphere.asynchbeans.Work;
import com.ibm.websphere.asynchbeans.WorkItem;
import com.ibm.websphere.asynchbeans.WorkManager;

public class MyWorkManager
{
/**
* static reference to work manager
*/
private static WorkManager sManager = null;

/**
* Indicator for initialized
*/
private static boolean sInitialized = false;

/**
* Only public entity. Send Thread/Runnable to this method to launch
*
* @param aRunnable Thread to run
* @throws Exception
*/
public static void start(Runnable aRunnable) throws Exception
{
new MyWorkManager(aRunnable, false);
}

public static void start(Runnable aRunnable, boolean isDaemon) throws Exception
{
new MyWorkManager(aRunnable, isDaemon);
}

/**
* Returns/initialized reference to WorkManager
*
* @return WorkManager
*/
private static WorkManager getWorkManager()
{
if ( sInitialized == false )
{
sInitialized = true;
if(sManager == null)
{
try
{
InitialContext ctx = new InitialContext();
String jndiName = “wm/myworkmanager”;
if ( jndiName != null && jndiName.length() > 0 )
{
sManager = (WorkManager)ctx.lookup(jndiName);
}
else
{
//log error
}
}
catch(Exception ex)
{
throw ex;
}
}
}
return sManager;
}

/**
* Private constructor. Calling this starts the thread in the appropriate manner
*
* @param aRunnable
* @throws Exception
*/
private MyWorkManager(Runnable aRunnable, boolean isDaemon) throws Exception
{
WorkManager wm = getWorkManager();
if ( wm != null )
{
ThreadWorker tw = new ThreadWorker(aRunnable);
WorkItem wi = wm.startWork(tw, isDaemon);
}
else
{
throw new Exception(“Unable to retrieve WorkManager”);
}

}

/**
* Work wrapper for the underlying Runnable thread
*
*/
public class ThreadWorker implements Work
{
/**
* Reference to Runnable object
*/
private Runnable mChild;

/**
* Constructor
*
* @param aRunnable Runnable object
*/
public ThreadWorker(Runnable aRunnable)
{
mChild = aRunnable;
}

/* (non-Javadoc)
* @see javax.resource.spi.work.Work#release()
*/
public void release()
{

}

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run()
{
if ( mChild != null )
{
mChild.run();
}
}

};
}

The application I manage at work is a client/server application written entirely in java.  My company for years has been an IBM shop, so we have a large Websphere presence which is where the server is deployed.  The application had been running on Websphere 5.1 for a few years and was fairly recently migrated to Websphere 6.0 to remain on a supported version of Websphere.  Because the end of life for Websphere 6.0 is September 2010, we’re starting to plan for another upgrade now (we have major releases in January and June, so we’re targeting the June ’10 release for the upgrade).  Websphere 6.1, if IBM holds to it’s pattern of every 2 years or so will remain supported until September 2012, however there’s no current end of life date documented yet (link).  To get the longest life possible, I’m looking at Websphere 7.0 as the target platform for our June ’10 upgrade.

We have RAD 7.5 in house and a couple members of my team have installed it.  I’ve been working on getting a local WAS 7.0 server up and running and getting our app deployed on it.  There are some major differences between Websphere 5.1/6.0 and 7.0.  I won’t go into details as those are readily available on IBM’s website, but would like to share some of my observations and pain so far.

Application Background: The server side of our application is effectively broken down into 2 pieces.  One component is what we call a provision server that is essentially a cache of configuration data read from DB2.  This configuration information contains rules which drive how the second component operates.  The second component is the main workhorse app which receives a request, and creates a response based on configuration data retrieved from the provision server (if necessary) and data retrieved from any number of other applications we interface with.  We have 2 provision server jvms for load balancing and fail over and roughly 20 app engine jvms spread across 2 data centers (the app engine hosts roughly 3500 end users and we target 200 users per jvm…roughly).

Unsolved Problem 1 – Remote EJB calls across separate local jvm/profiles doesn’t work: Now that you have a high level view of our applications architecture, here’s my first dilema which I haven’t found a solution to.  Websphere now has the concept of profiles.  Basically a profile equates to a jvm instance.  It’s a little more than that, but that’s a good enough understanding for now.  So if you want 2 distinct/separate JVMs configured differently, you would need to create 2 profiles and create servers associated with each profile.  In all our lifecycles, we have distinct jvms setup for provision and app engine – we don’t cluster the app engine with the provision server because we want our dev/test lifecycles to mirror production, and production is separate because we don’t want a 1:1 correlation of provision server to app engine as the provision server is memory intensive and 2 jvms can handle the entire app engine load very effectively.  So I want to replicate that with my RAD 7.5 setup – 1 app engine jvm and 1 provision server jvm running locally within RAD 7.5.  That requires 2 separate profiles to be created, then a server defined and associated for each one.  No problem.  Where I run into problems is at runtime.  The app engine makes remote (cross-jvm) EJB calls to the provision server.  That requires a JNDI lookup of an EJB remote home object.  For some reason, jvm 1 cannot see any JNDI objects that are stored in jvm 2.  When I do an initial context and dump out the contents, all I ever get are the local JVM’s name server items.  But if I point the local server at one of our test lifecycle provision servers, it sees those just fine.  I have no idea why 1 local jvm can’t access another local jvm’s name server.  I’m not sure if it’s because of the base version of Websphere that’s running, or some other limitation of the development environment, but that is one hurdle I can’t get over.  So my workaround is to just deploy the provision server and app engine in the same jvm as local ejb calls work just fine.

Solved Problem 2 – creating a secure socket for an outbound ssl SOAP request: The app engine is a portal of sorts.  It will call any number of external systems to retrieve data and aggregate that data as needed based on the request.  There are several system we currently interface and several protocols we use to do so…SOAP over SSL, EJB, JDBD for example.  We use apache soap (old, but still works) to call several external systems, one of which is the main system we interface with.  In Websphere 5.1 and 6.0, we set our own JKS truststore for the request using the javax.net.ssl.truststore property.  This truststore contains the SSL certificates of our target URL.  It just worked.  Now we move to Websphere 7.0 and the same requests which work in a local WAS 6.o server no longer work.  After much digging and reading of documentation, it turns out WAS 6.1 (and 7.0) changed how SSL security was handled.  Long story short, when WAS sees a secure socket being created, it assumes responsibility for securing that connection (Big Brother?) instead of letting you do your own thing.  Now, there are ways around it, but the point is it is NOT backwards compatible.  The quick fix for this was to put the SSL certs in Websphere’s default truststore (go to the admin console, under security and then ssl configuration and you can find a whole bunch of related config).  There are several articles on this and I highly recommend reading the Websphere Application Server V7.0  Security Guide for background on this.  It is extremely helpful.

These are 2 of the biggest pain points I’ve hit so far, but I have a ways to go before I can say the app is fully certified on Websphere 7.0.  If I run into any more issues, I’ll update this post.

Oh, and before I forget to mention, when migrating from RAD 6 to RAD 7+, don’t forget to MIGRATE your JEE projects.  There are project metadata differences between the 2 which aren’t compatible.  Found this out the hard way.

The 2009 Cary Jr Trojans season is over.  Last week was superbowl weekend.  4 out of 5 Cary bantam teams made the playoffs, and 3 out of those 4 made the superbowl.  Truly a fantastic group of 7 & 8 year olds who should continue to be successful as they move through the levels and into high school.  Some say the current Cary Grove high school team had the same success when they were bantams.  Let’s hope as a group our bantams can be just as successful.

Oh, guess which of the 3 teams lost?  Yeah, mine.  It was a heartbreaking loss.  We beat ourselves.  Mistakes, penalties, and a fumble on the 3 yard line.  We lost 0-7 to Woodstock.  I wouldn’t feel so bad if they dominated us, but we really should have won that game.  Our defense held their own again, with the only big play for Woodstock coming with our middle linebacker on the sidelines recovering from a hit.  11-1 is a fantastic season, but the loss is a bitter pill to swallow.  Only 7 months to wait for next season.

I have a project at work where we’re looking to present a user with an edit message if they’ve changed anything within a web page and haven’t saved the form before closing the page to stop them from losing changes.  The following example works with IE 6 (which is our corporate browser).  It does not seem to work with firefox, and I haven’t checked with any other browser since our need is isolated to IE.

<html>
<body>
<script type=”text/javascript”>
document.write(“Hello World!”);
var needToConfirm = false;
//Call this function if some changes is made to the web page and requires an alert
//you could call this is Keypress event of a text box or so…
function setDirtyFlag()
{
needToConfirm = true;
}

//this could be called when save button is clicked
function releaseDirtyFlag()
{
needToConfirm = false; //Call this function if dosent requires an alert.
}
window.onbeforeunload = confirmExit;
function confirmExit()
{
if (needToConfirm)
return “You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?”;
}
</script>
</body>
</html>

Follow

Get every new post delivered to your Inbox.