Aug 11 2010

Splash Screen for Blackberry

I am a bit confused as to why there isn’t a standard library for splash screens in mobile apps. So here is an implementation of a blackberry splashscreen. I believe the comments are sufficient to work out what is going on.


import java.util.Timer;
import java.util.TimerTask;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.KeyListener;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.container.MainScreen;

/**
 * <p>Every application needs a splash screen.</p>
 * <p>A splash screen should have the following rules</p>
 * <ul>
 * 	<li>Display effectively what the product is.</li>
 *  <li>Be removed automatically after a duration if not exited manually.</li>
 *  <li>You must be able to manually exit the splash screen before the desired amount of time has been exceeded.</li>
 * </ul>
 *
 * 	@author Kevin Bayes
 *
 *	<p><i>This was modified by the splash screen tutorial found on blackberry.com.</i></p>
 *
 */
final public class SplashScreen extends MainScreen {

	  	private MainScreen next;
	    private Timer timer = new Timer();
	    private UiApplication application;

	    //This splash screen is an image read from the root folder of the application
	    private static final Bitmap _bitmap = Bitmap.getBitmapResource("splash.png");

	    public SplashScreen(UiApplication ui, MainScreen next) {
	        super (Field.USE_ALL_HEIGHT|Field.FIELD_LEFT);
	        this.application = ui;
	        this.next = next;
	        this.add(new BitmapField(_bitmap));

	        /*
	         * create a listener to allow the user to exit the splash screen
	         * manually or override the navigation events as done below.
	         *
	         * the splash screen listener should implement net.rim.device.api.system.KeyListener.
	         *
	        */
	        //SplashScreenListener listener = new SplashScreenListener(this);
	        //this.addKeyListener(listener);

	        //create a timer to count down to the splash screens exit
	        timer.schedule(new ExitSplashCountDown(), 5000);
	        application.pushScreen (this);
	    }

	    /**
	     * <p>When the splash screen exits three things happen</p>
	     * <ol>
	     * 	<li>The timer is canceled.</li>
	     * <li>You pop the splash screen off the stack.</li>
	     * <li>You push the main screen onto the stack.</li>
	     * </ol>
	     */	    public void dismiss() {
	        timer.cancel();
	        application.popScreen (this);
	        application.pushScreen (next);
	    }

	 	    /**
	     *  <p>This {@link TimerTask} is used to make sure the splash screen exits and
	     *  <b>does not display forever</b>.</p>
	     *
	     * @author Kevin Bayes
	     *
	     */	    private final class ExitSplashCountDown extends TimerTask {
	        public void run() {
	           ExitSplashThread dThread = new ExitSplashThread();
	           application.invokeLater (dThread);
	        }
	    }

	  	    /**
	     * <p>Used by the {@link ExitSplashCountDown} to exit the splash screen.</p>
	     *
	     * @author Kevin Bayes
	     *
	     */	    private final class ExitSplashThread implements Runnable {
	        public void run() {
	             dismiss();
	        }
	    }    

	    /*
	     * When you click the navigation then the screen should exit and go to your applications main screen
	     *
	     * (non-Javadoc)
	     * @see net.rim.device.api.ui.Screen#navigationClick(int, int)
	     */
	    protected boolean navigationClick(int status, int time) {
	    	 dismiss();
	         return true;
	    }

	    /*
	     * Make sure nothing happens when the navigation senses movement
	     *
	     * (non-Javadoc)
	     * @see net.rim.device.api.ui.Screen#navigationMovement(int, int, int, int)
	     */
	    protected boolean navigationMovement(int dx, int dy, int status, int time) {
	    	return false;
	    }

	    /*
	     * Make sure nothing happens when unclick occurs
	     *
	     * (non-Javadoc)
	     * @see net.rim.device.api.ui.Screen#navigationUnclick(int, int)
	     */
	    protected boolean navigationUnclick(int status, int time) {
		    return false;
	    }

}


Aug 4 2010

Spring Security Minimal Setup

Sometimes you need to do a project and it doesn’t have to have the worlds best security. But rather something small that is easy to implement where you can statically add a user with roles.

So as an introduction I would like to show you the minimum to add security to a java web application.

1. Add the spring-context.xml to your WEB-INF folder.

The spring-context xml should look something like this:

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans
 xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance
 xmlns:sec=”http://www.springframework.org/schema/security
 xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd“>

 <sec:http auto-config=”true” access-denied-page=”/denied.htm”>
  <sec:intercept-url pattern=”/**” access=”ROLE_USER”/>
  <sec:concurrent-session-control max-sessions=”100″ exception-if-maximum-exceeded=”true”/>
 </sec:http>

 <sec:authentication-provider>
  <sec:user-service>
   <sec:user password=”pass” name=”user” authorities=”ROLE_USER”/>
  </sec:user-service>
 </sec:authentication-provider>
</beans>

Above you can see we have declared a user “user” with password “pass”, and this user has the authority of a “ROLE_USER”.

In the <sec section above we declare the security to filter out anything that tries to get into the root or below folders, unless the user logs in and his/her role is that of “ROLE_USER”.

2. Considering there is nothing linking or indicating to the web application that this security context even exists we shall inform the webapplication that it should use a filter for all requests. The filter will dispatch all requests to the setup spring security. To do this you should add the following lines to the web.xml file in the WEB-INF directory.

   <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
     /WEB-INF/security-context.xml
    </param-value>
  </context-param>

<filter>
 <filter-name>springSecurityFilterChain</filter-name>
 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
 <filter-name>springSecurityFilterChain</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

3. Dont feels its odd that you have not created a login page as spring will provide a default.

That is how you add simple authentication to your application.


Jul 22 2010

Read an Oracle Stored Procedures Cursor using Spring

I came accross the problem where hibernate is restricted in the way it can access an oracles stored procedure that returns a reference cursor. In hibernate the reference cursor should be the first parameter in the stored procedure. Now working with stored procedures writted differently you could always just extend the “org.springframework.jdbc.object.StoredProcedure” abstract class, if you are using spring that is. 

Since my blog is all about the samples here it is:


package com.bayestech.sampleprocedure; 

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types; 

import javax.sql.DataSource; 

import oracle.jdbc.driver.OracleTypes; 

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.StoredProcedure; 

import uk.co.pruhealth.admin.communication.notificationengine.PolicyLinks; 

/**
 * This class reads a stored procedure named 'sample_procedure' which has the following usag:
 * call sample_procedure (? <= p_Number_Input, ? <= p_String_Input, ? <= p_Date, ? => Pr_Returned_Cursor, ? => Pr_Error_Code, ? => Pr_Error_Message)
 *
 *
 * @author Kevin Bayes
 *
 */
public class SampleStoredProcedure extends StoredProcedure {

 /** Name of procedure in database. */
 public static final String PROC_NAME = "sample_procedure";�
 public GetPolicyLinksStoredProcedure(DataSource ds) {
  super(ds, PROC_NAME);

  declareParameter(new SqlParameter("p_Number_Input", Types.NUMERIC));
  declareParameter(new SqlParameter("p_String_Input", Types.VARCHAR));
  declareParameter(new SqlParameter("p_Date", Types.DATE));
  declareParameter(new SqlOutParameter("Pr_Returned_Cursor", OracleTypes.CURSOR, new RowMapper() {
   public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    SampleReturnClass sampleClass = new SampleReturnClass();
    policyLink.setColumn1Name(rs.getString("COLUMN_1_NAME"));
    policyLink.setColumn2Name(rs.getString("COLUMN_2_NAME"));
    policyLink.setColumn3Name(rs.getString("COLUMN_3_NAME"));
    return sampleClass;
   }
  }));
  declareParameter(new SqlOutParameter("Pr_Error_Code", Types.NUMERIC));
  declareParameter(new SqlOutParameter("Pr_Error_Message", Types.VARCHAR));

     compile();
 }   

}

Once you have created the above class you need to execute it by setting the datasource and passing in the desired parameters like so:


public Collection getList(DataSource dataSource, Long inputNumber, String inputString, Date effectiveDate) {

	SampleStoredProcedure sampleStoredProcedure = new SampleStoredProcedure(dataSource);
	Map parameters = new HashMap();
	parameters.put("p_Number_Input", targetEntityNumber);
	parameters.put("p_String_Input", null);
	parameters.put("p_Date", effectiveDate);

       	Map m = SampleStoredProcedure.execute(parameters);
       	return (Collection) m.get("Pr_Returned_Cursor");
}

And that is all there is to it!


Feb 4 2010

Integrating Weblogic EJB 3.0 Message-Driven Beans and TIBCO ems

Download

Sample Ejb project

Introduction

So I recently tried to create a EJB3 (no annotations, but rather descripter files) message driven bean that runs on weblogic 10.1 and processing messages from a TIBCO ems server. Having experienced how easy it is to implement I though I would share my experience. I will not go into how to setup a queue and will start with the weblogic config and java implementation.

Weblogic Config

In order for weblogic to connect to the TIBCO ems server you need to place the TIBCOjms.jar (or similarly named file) in your user_project/lib directory. Next you should start weblogic.

Now, go to the console -> Services -> Messaging -> JMS Module. Here we will setup a foreign connection to the TIBCO ems server.

Add a new foreign server  I called mine emsForeignServer.

In the initial context factory you need to use  com.tibco.tibjms.naming.TibjmsInitialContextFactory, and in the connection url should be the url to the tibco jms naming mine is tibjmsnaming://localhost:7222

Now inorder for us to connect to the server lets setup a connection factory. Click on the tab and ask you tibco administrator to send you the jndi name of the QueueConnectionFactory. Place that name in the remote jndi name field and place any reference you would like in the local jndi name field, I named mine EmsQueueConnectionFactory.

The second thing you need is to setup a reference to the destination queue. You do this by clicking on destinations tab and adding a destination. I gave mine the name of Request Queue. And similarly to the Connection factory you need to ask you tibco administrator for the jndi reference to the destination queue. I named my local jnd reference to ems.message.request.

All you need to do now is save and activate and you have your weblogic is setup for messaging to TIBCO ems.

The resulting xml config file should look similar to this :



<?xml version='1.0' encoding='UTF-8'?>

<weblogic-jms xmlns="http://www.bea.com/ns/weblogic/90"

       xmlns:sec="http://www.bea.com/ns/weblogic/90/security"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:wls="http://www.bea.com/ns/weblogic/90/security/wls"

       xsi:schemaLocation="http://www.bea.com/ns/weblogic/920 http://www.bea.com/ns/weblogic/920.xsd">

  <foreign-server name="TibcoEmsQueue">

    <default-targeting-enabled>true</default-targeting-enabled>

    <foreign-destination name="DestinationQueue">

      <local-jndi-name>ems.message.request</local-jndi-name>

      <remote-jndi-name>TEST_QUEUE</remote-jndi-name>

    </foreign-destination>

    <foreign-connection-factory name="LocalConnectionFactory">

      <local-jndi-name>LocalQueueConnectionFactory</local-jndi-name>

      <remote-jndi-name>QueueConnectionFactory</remote-jndi-name>

    </foreign-connection-factory>

    <initial-context-factory>com.tibco.tibjms.naming.TibjmsInitialContextFactory</initial-context-factory>

    <connection-url>tibjmsnaming://localhost:7222</connection-url>

  </foreign-server>

</weblogic-jms>

Java Implementation

First of all this is a simplified solution I will not get into specifics of creating a delegate to handle the messages from the queue or spring injection but those will be handled in a future post.

So lets get started. I created a maven parent project called sample-software. In this maven project I have a module called sample-ejb which is of type ejb. Now the reason why this was done was to show you how to package a ejb in a ear file for deployment without having to write another tutorial.

Okay, so now you should create 1 maven project with 2 maven modules. The result should look something like :

    +samples

     |-ejb

     |  -pom.xml

     |-ear

     |  -pom.xml

     |-pom.xml

The parent pom.xml should look something like:



  <modelVersion>4.0.0</modelVersion>

  <groupId>bayestech</groupId>

  <artifactId>samples</artifactId>

  <packaging>pom</packaging>

  <name>Sample Projects</name>

  <version>0.0.1-SNAPSHOT</version>

  <modules>

  	<module>ejb</module>

  	<module>ear</module>

  </modules>

The ejb pom.xml should look something like:



    <parent>

    <artifactId>samples</artifactId>

    <groupId>bayestech</groupId>

    <version>0.0.1-SNAPSHOT</version>

  </parent>

  <modelVersion>4.0.0</modelVersion>

  <groupId>bayestech</groupId>

  <artifactId>ejb</artifactId>

  <packaging>ejb</packaging>

  <name>Sample EJB</name>

  <version>0.0.1-SNAPSHOT</version>

  <description>Sample ejb project</description>

    <dependencies>

        <dependency>

            <groupId>javax.ejb</groupId>

            <artifactId>ejb</artifactId>

            <version>3.0</version>

            <scope>provided</scope>

        </dependency>

        <dependency>

            <groupId>javax.annotation</groupId>

            <artifactId>jsr250-api</artifactId>

            <version>1.0</version>

            <scope>provided</scope>

        </dependency>

        <dependency>

            <groupId>javax.jms</groupId>

            <artifactId>jms</artifactId>

            <version>1.1</version>

            <scope>provided</scope>

        </dependency>

 </dependencies>

   <build>

        <plugins>

        	<plugin>

 		<groupId>org.apache.maven.plugins</groupId>

 			<artifactId>maven-ejb-plugin</artifactId>

 			<configuration>

 				<ejbVersion>3.0</ejbVersion>

 			</configuration>

 		</plugin>

 	</plugins>

 </build>

A thing to note is that I marked all dependencies as provided. This is because

I am going to add them all to the ear file APP-INF/lib folderThe ear pom.xml should look something like:



  <parent>

    <artifactId>samples</artifactId>

    <groupId>bayestech</groupId>

    <version>0.0.1-SNAPSHOT</version>

  </parent>

  <modelVersion>4.0.0</modelVersion>

  <groupId>bayestech</groupId>

  <artifactId>ear</artifactId>

  <packaging>ear</packaging>

  <name>Sample ear</name>

  <version>0.0.1-SNAPSHOT</version>

   <description>A bundle of all the applications</description>

  <dependencies>

  	<!-- ******************************************************************** -->

  	<!-- ADD ALL OUR PROJECTS 												  -->

  	<!-- ******************************************************************** -->

    <dependency>

    	<groupId>bayestech</groupId>

      	<artifactId>ejb</artifactId>

      	<version>${project.version}</version>

      	<type>ejb</type>

    </dependency>

    <!-- ******************************************************************** -->

  	<!-- ADD ALL DEPENDENCIES												  -->

  	<!-- ******************************************************************** -->

  	<!-- A ******************************************************************** -->

  	<!-- B ******************************************************************** -->

  	<!-- C ******************************************************************** -->

    <dependency>

      <groupId>commons-logging</groupId>

      <artifactId>commons-logging</artifactId>

      <version>${commons.logging.version}</version>

    </dependency>

  	<!-- D ******************************************************************** -->

  	<!-- E ******************************************************************** -->

  	<!-- F ******************************************************************** -->

  	<!-- G ******************************************************************** -->

  	<!-- H ******************************************************************** -->

  	<!-- I ******************************************************************** -->

  	<!-- J ******************************************************************** -->

  	<!-- K ******************************************************************** -->

  	<!-- L ******************************************************************** -->

  	<dependency>

      <groupId>log4j</groupId>

      <artifactId>log4j</artifactId>

      <version>${log4j.version}</version>

      <scope>runtime</scope>

      <exclusions>

        <exclusion>

          <groupId>com.sun.jdmk</groupId>

          <artifactId>jmxtools</artifactId>

        </exclusion>

        <exclusion>

          <groupId>com.sun.jmx</groupId>

          <artifactId>jmxri</artifactId>

        </exclusion>

      </exclusions>

    </dependency>

  	<!-- M ******************************************************************** -->

  	<!-- N ******************************************************************** -->

  	<!-- O ******************************************************************** -->

  	<!-- P ******************************************************************** -->

  	<!-- Q ******************************************************************** -->

  	<!-- R ******************************************************************** -->

  	<!-- S ******************************************************************** -->

  	<!-- T ******************************************************************** -->

  	<!-- U ******************************************************************** -->

  	<!-- V ******************************************************************** -->

  	<!-- W ******************************************************************** -->

  	<!-- X ******************************************************************** -->

  	<!-- Y ******************************************************************** -->

  	<!-- Z ******************************************************************** -->  </dependencies>

   <!-- Specify the content of generated artifact. -->

  <build>

<!-- Specify the final name of the artifact. -->

    <finalName>sample-ear</finalName>

    <defaultGoal>package</defaultGoal>

<plugins>

      <plugin>

        <groupId>org.apache.maven.plugins</groupId>

        <artifactId>maven-compiler-plugin</artifactId>

        <!-- Specify used Java version. -->

        <configuration>

          <source>1.5</source>

          <target>1.5</target>

        </configuration>

      </plugin>

<plugin>

        <groupId>org.apache.maven.plugins</groupId>

        <artifactId>maven-ear-plugin</artifactId>

        <configuration>

        	<displayName>Sample by bayestech</displayName>

            <version>5</version>

<!-- set default location -->

          <defaultJavaBundleDir>APP-INF/lib</defaultJavaBundleDir>

          <!-- Specify modules to include. -->

          <modules>

          	<!-- Include EJB Modules -->

<ejbModule>

               <groupId>bayestech</groupId>

               <artifactId>ejb</artifactId>

               <bundleDir>/</bundleDir>

            </ejbModule>

</modules>

          <resourcesDir>src/main/resources</resourcesDir>

        </configuration>

      </plugin>

</plugins>

</build>

Above is the ear configuration which the explanation is out of the scope of this tutorial. Email me if you need help or post a comment.

Finally on to the good stuff.

Okay now that we have the project setup after a long time of reading we are ready to create our mdb.

Firstly, create a weblogic-ejb-jar.xml file in the ejb/src/main/resources/META-INF/ directory, with the following configuration:



<?xml version="1.0" encoding="UTF-8"?>

<weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/10.0" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://www.bea.com/ns/weblogic/10.0 http://www.bea.com/ns/weblogic/10.0/weblogic-ejb-jar.xsd">

    <description>Messaging Enterprise JavaBeans</description>

    <weblogic-enterprise-bean>

        <ejb-name>SampleMDB</ejb-name>

        <message-driven-descriptor>

        	<pool>

        		<max-beans-in-free-pool>10</max-beans-in-free-pool>

        		<initial-beans-in-free-pool>10</initial-beans-in-free-pool>

        		<idle-timeout-seconds>60000</idle-timeout-seconds>

        	</pool>

        	<destination-jndi-name>ems.message.request</destination-jndi-name>

        	<connection-factory-jndi-name>LocalQueueConnectionFactory</connection-factory-jndi-name>

    	</message-driven-descriptor>

    </weblogic-enterprise-bean></weblogic-ejb-jar>

The destination-jndi-name and connection-factory-jndi-name properties are the local jndi names we specified in the weblogic jms module right in the beginning of the tutorial.

Now in the ejb-jar.xml file you need the following to bind your class to the message bean name:



<display-name>Message Beans</display-name>	<enterprise-beans>

      <message-driven>

      	  <!-- Bean definition -->

         <ejb-name>SampleMDB</ejb-name>

         <ejb-class>bayestech.sample.message.SampleMDB</ejb-class>

         <messaging-type>javax.jms.MessageListener</messaging-type>

         <transaction-type>Container</transaction-type>

<!-- Listen to a queue -->

 		<message-destination-type>javax.jms.Queue</message-destination-type>

<!-- Activation criteria -->

         <activation-config>

         	<activation-config-property>

         		<activation-config-property-name>acknowledgeMode</activation-config-property-name>

         		<activation-config-property-value>Auto-acknowledge</activation-config-property-value>

         	</activation-config-property>

         </activation-config>

</message-driven>

   </enterprise-beans>

<assembly-descriptor>

    <container-transaction>

       <method>

          <ejb-name>SampleMDB</ejb-name>

          <method-name>onMessage()</method-name>

       </method>

       <trans-attribute>NotSupported</trans-attribute>

    </container-transaction>

 </assembly-descriptor>

In my environment the queue is not transacted, hence the trans-attribute is NotSupported.

Okay now all we need to do is create a MDB implementation in java which should look like this:



package bayestech.sample.message;import javax.ejb.EJBException;

import javax.ejb.MessageDrivenBean;

import javax.ejb.MessageDrivenContext;

import javax.jms.Message;

import javax.jms.MessageListener;

public class SampleMDB  implements MessageDrivenBean, MessageListener {

static final Log log = LogFactory.getLog(SampleMDB.class);

/* (non-Javadoc)

  * @see javax.ejb.MessageDrivenBean#ejbRemove()

  */

 public void ejbRemove() throws EJBException {

 	// TODO Auto-generated method stub

}

 /* (non-Javadoc)

  * @see javax.ejb.MessageDrivenBean#setMessageDrivenContext(javax.ejb.MessageDrivenContext)

  */

 public void setMessageDrivenContext(MessageDrivenContext arg0)

 		throws EJBException {

 	// TODO Auto-generated method stub

}

public void onMessage(Message arg0) {

 	log.info("it worked!!!!");

 }

}

Now build the maven project and deploy to weblogic and everything should work. Well I hope this gives you the base for a MDB. I have a spring context injected mdb if anyone is interested. I will quickly do the sample project and upload it at a later stage.

Conclusion

This is really simple way of implementing mdb in weblogic with a foreign TIBCO ems queue.


Error in my_thread_global_end(): 2 threads didn't exit