Tabs in a TextBox

Anyone who uses the web and happens to be programmer knows that at some point you are in a HTML TextBox and as your typing away you hit the tab to indent the line….. and you end up in the next field.

This is correct, but when you are typing in code it can get really annoying and you end up having to use the space bar to fake out the indentation.

We’ll, I couldn’t take it anymore so I wrote my own JQuery plug-in that will allow you to do real tabbing in an TextBox. Let me state a few things:

  • I know there are others out there but most had issues where it would support the tab but not put the cursor at the tab or if it was a tab that caused the TextBox to invoke the vertical scrollbar, it would screw up. I’ve addressed these issues
  • Some of the other libraries, if you cut/paste in text with tabs it wouldn’t follow the indentation of the previous line. Mine does
  • This plug works perfectly in FireFox and very well in I.E. (there appears to be a minor bug with I.E. placing an ASCII 10 character and not just a 13 so it gets a little sketchy cursor positioning wise under a specific instance where you had a previously tabbed line and you hit enter when the cursor is in the middle of a word). As I don’t use I.E. I’m not going to worry about it unless someone asks me to 🙂

Requirements

The Code

<html>
<head>
<script type="text/javascript" src="jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="jquery-fieldselection.js"></script>
<script type="text/javascript">
(function( $ ) {
       $.fn.tabSupport = function() {
               var CAR_RETURN = '\n';
               var TAB = '\t';
               this.keydown(function(event) {
                       if (event.which == 9) {
                               event.preventDefault();
                               var pos = $(this).getSelection();
                               scrollLoc = $(this)[0].scrollTop;
                               pos.start = pos.start + 1;
                               pos.end = pos.end + 1;
                               $(this).replaceSelection(TAB);
                               if (!$.browser.msie) positionCursor($(this), pos, buildTabs($(this).val(), pos));
                               $(this)[0].scrollTop = scrollLoc; 
                       }
               });

               this.keyup(function(event) {
                       if (event.which == 13) {
                               var pos = $(this).getSelection();
                               var tabs = buildTabs($(this).val(), pos);
                               scrollLoc = $(this)[0].scrollTop;
                               if (tabs.length > 0) {
                                       $(this).replaceSelection(tabs);
                               }
                               if (!$.browser.msie) positionCursor($(this), pos, tabs);
                               $(this)[0].scrollTop = scrollLoc; 
                       }
               });

               function buildTabs(data, pos) {
                       var prevLineEnd = data.substring(0, pos.end).lastIndexOf(CAR_RETURN);
                       var prevLineStart = ($.browser.msie)
                               ?data.substring(0, prevLineEnd-1).lastIndexOf(CAR_RETURN)
                               :data.substring(0, prevLineEnd-1).lastIndexOf(CAR_RETURN)+1;
                       if (data.charCodeAt(prevLineStart) == 10) prevLineStart ++; 

                       var tabs = '';
                       var tc = 0;
                       for (var i = prevLineStart; i <= prevLineEnd; i++) {
                               if (data.charAt(i) != TAB) break;
                               tabs += TAB;
                               tc++;
                       }
                       $("#tabCount").val(tc);
                       return tabs;
               }

               function positionCursor(obj, pos, tabs) {
                       if (obj[0].setSelectionRange) {
                               obj[0].setSelectionRange(pos.start+tabs.length, pos.end+tabs.length);
                       }
                       else if (obj[0].createTextRange) {
                           var range = obj[0].createTextRange();
                           range.collapse(true);
                           range.moveEnd('character', pos.start);
                           range.moveStart('character', pos.end);
                           range.select();
                       }
               }
       }
}) ( jQuery );

Usage

<script type="text/javascript">
$(function() {
       $('#testTextArea').tabSupport();
});
</script>

<form>
<textarea id="testTextArea" rows="20" cols="40"></textarea>
</form>

Quick Explanation

Without going into too much detail the code watches for the ENTER and TAB button to be pressed. When the TAB button is pressed it’s normal functionality is disabled (event.preventDefault();) then it uses the fieldSelection library to find the position in the TextArea and then inserts a ‘\t’ into wherever TAB was pressed.

The ENTER button when pressed isn’t handled till after the button is up so that the browser still causes the ENTER function. If you do it on keyPress and not keyUp the browser will not do the line feed and the TextBox won’t scroll (even if you inject a \n). On keyUp the code looks are the previous line, determines how many \t’s there are and inserts that amount into the beginning of the existing line. In this way we support cut/paste as well as people hopping around in the document and changing the tabbing.

Example

Click here to try it!

Posted in JavaScript, Programming | Tagged , | 2 Comments

Setting on a Set()

Maybe this post should be called ‘Setting on a Sunset()’ but Oracle now owns Java, and ‘Setting on an OracleSet()’ sounds programmatically correct but it just doesn’t have the same ring (or the feel of a nice drink in your hand while sitting on a beach….. writing java ;))

Anyway, there are many times when dealing with an ORM that you might want to call a setter on an object that exists in a 1-Many relationship and have that set() method do some other work.

For instance, say you have two objects (using JPA Annotations):

@Entity
@Table(name="USER")
public class User {
   @Id
   @Column(name="ID")
   private Long id;

   @Column(name="NAME")
   private String name;

   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID", nullable = false)
   private Company company;
   
   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }

   public Company getCompany() { return company; }
   public void setCompany(Company company) { this.company = company }
}

@Entity
@Table(name="COMPANY")
public class Company {
   @Id
   @Column(name="ID")
   private Long id;

   @Column(name="NAME")
   private String name;

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", 
          cascade = { CascadeType.MERGE, CascadeType.PERSIST })
   private Set<User> users = new HashSet<User>(0);

   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }

   public Set<User> getUsers() { return users; }
   public void setUsers(Set<User> users) { this.users = users; }
}

This is a pretty straightforward, standard way of making a 1-Many relationship in an ORM (my experience is with Hibernate mainly).

Side note:
My HashSet was initially set to a size of 0. If a Collection has the possibility of staying empty you should initialize it to 0 because otherwise some implementation will immediate make it 10 spaces and you will waste memory. However, initializing it to 0 also means that we take a small performance hit when we first put something into it since it has to allocate space. I’m just suggesting that you put some thought into it 😉

So lets start using our objects and set some things:

... some method definition...
Company company = new Company();
company.setName("World Wide Wicket");

User user = new User();
user.setName("Sloan");
user.setCompany(company);
company.addUser(user);
.... more code ...

Doesn’t that seem a bit annoying? You set the Company in the User but then you have to add the User to the Companies list of Users. Wouldn’t it be better to just call one method to accomplish this? Shouldn’t you just have to set the Company in the User and that be it (or just add the User to the list of Users in the Company)?

So I was thinking about this and I came up with a few different ways. I’ll go over them and also what is good/bad about them as well as any other pitfalls I have identified.

Custom Set implementation

The first thing I thought was: Well, I can create my own collection so that when it is called it will do things for me. That would look something like:

public class Company {
@Id
   @Column(name="ID")
   private Long id;

   @Column(name="NAME")
   private String name;

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", 
          cascade = { CascadeType.MERGE, CascadeType.PERSIST })
   private Set<User> users = new UserHashSet<User>(this);

   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }

   public Set<User> getUsers() { return users; }
   public void setUsers(Set<User> users) { this.users = users; }

   public class UserHashSet extends HashSet<User> {
      private Company company;

      public UserHashSet(Company company) {
         this.company = company;
      }

      public void add(User user) {
         super.add(user);
         user.setCompany(company);
      }

      ... do the same for addAll ...
   }
}

Pros:

  • The code is pretty straight forward for the developers when adding:
company.getUsers().add(user);

Cons:

  • You have to code a whole other class
  • If someone calls company.setUsers() they can override your UserHashSet and add() will no longer work correctly
  • Developers, if playing it safe, would still probable do:
company.getUsers().add(user);
user.setCompany(company);

So, as slick as this may be in some ways, I don’t think it’s the way to go because it allows the developers to still do additional work as well as really screw things up.

Code in set() and an add() method

Another option is to put some code in the User.setCompany() and create a method in the Company called addUser(). Something like:

@Entity
@Table(name="USER")
public class User {
   @Id
   @Column(name="ID")
   private Long id;

   @Column(name="NAME")
   private String name;

   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID", nullable = false)
   private Company company;
   
   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }

   public Company getCompany() { return company; }
   public void setCompany(Company company) { 
      this.company = company 
      company.getUsers().add(this);
   }
}

@Entity
@Table(name="COMPANY")
public class Company {
   @Id
   @Column(name="ID")
   private Long id;

   @Column(name="NAME")
   private String name;

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", 
          cascade = { CascadeType.MERGE, CascadeType.PERSIST })
   private Set<User> users = new HashSet<User>(0);

   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }

   public Set<User> getUsers() { return users; }
   public void setUsers(Set<User> users) { this.users = users; }

   public void addUser(User user) {
      user.setCompany(user);
   }
}

Pros:

  • Less code than the previous example
  • A little more direct in having the developer use it. They can do it either way and it will work

Cons:

  • Still allows developers to go around the addUser() method when adding a user. They can still call setUsers() and getUsers().add()

We could try solving it by doing:

   ... company object code ...
   public Set<User> getUsers() {
      return Collections.unmodifiableSet(users);
   }

   void setUsers(Set<User> users) {
      this.users = users;
   }

   public void addUser(User user) {
      user.setCompany(user);
   }

This would restrict the developer form using company.getUsers().add() and also hide the setUsers() from them.
The issue though is now User.setCompany() cannot call company.getUsers().add() so we have broken the User code.

The Best Solution?

Let me state that I don’t know if I have the best solution for this. This is what I came up with.

@Entity
@Table(name="USER")
public class User {
   @Id
   @Column(name="ID")
   private Long id;

   @Column(name="NAME")
   private String name;

   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID", nullable = false)
   private Company company;
   
   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }

   public Company getCompany() { return company; }
   public void setCompany(Company company) { 
      this.company = company 
      company.addUser(this);
   }
}

@Entity
@Table(name="COMPANY")
public class Company {
   @Id
   @Column(name="ID")
   private Long id;

   @Column(name="NAME")
   private String name;

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", 
          cascade = { CascadeType.MERGE, CascadeType.PERSIST })
   private Set<User> users = new HashSet<User>(0);

   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }

   public Set<User> getUsers() { 
      return Collections.unmodifiableSet(users); 
   }
   void setUsers(Set<User> users) { this.users = users; }

   void addUser(User user) {
      users.add(user);
   }

Pros:

  • This limits the developer to setting the Company/User relationship in only one way that we can control and set the relationship with
  • Less code than the first example, more controlled than the second

Cons:

  • Developers may be confused that they can only set the Company on the user object

So, it sounds like a simple thing but really I had a put a bit of thought into it. The main issue is that you need to control how the developer will do things and keep it constricted so that they are forced down a specific path so that you can manipulate the objects correctly.

If you think, or know, there is a better solution than this, please post it! No one said I was always going to get it right 🙂

Posted in Java, Programming | Tagged | 5 Comments

Spring, Quartz, and Persistence

Spring is great, Spring is fun, Spring is best when it’s one on one (props to George Michael).

No, really, Spring is a great architecture. Its easily configured, highly flexible, and comes with a ton of already coded utils for doing anything from REST based integration calls to quickly deployed Servlets.

One of the packages that you may eventually end up using it the Spring Scheduler. The Spring Scheduler is a Spring wrapper to the very nice scheduling library, Quartz. The Spring Scheduler is simple and easy until you have to worry about more than one server. As soon as you get into a clustered environment (especially one that you back the scheduling with a database) it starts to swagger like a frat boy during homecoming. Unless your careful it just may puke on you.

So you don’t waste 3 (yes 3) days on getting it setup and working I thought I’d go over what it takes to get Quartz to run in a Spring clustered environment with a db backend and actual usable Spring beans (autowiring, etc).

The first thing you will want to do it get the Quartz libraries. Careful now because the latest Quartz libs (2.x) don’t work with Spring. You have to use something earlier (at the time of this writing it’s at 1.8.6).
Here is the Maven dependencies for it:

	<dependency>
		<groupId>org.quartz-scheduler</groupId>
		<artifactId>quartz</artifactId>
		<version>1.8.5</version>
		<exclusions>
			<exclusion>
				<groupId>com.mchange.c3p0</groupId>
				<artifactId>com.springsource.com.mchange.v2.c3p0</artifactId>
			</exclusion>
		</exclusions>
	</dependency>

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-oracle</artifactId>
            <version>1.8.5</version>
        </dependency>

Please note that I excluded C3P0 because I already use it in most of my projects. If you don’t use C3P0 then your Maven dependencies will be:

	<dependency>
		<groupId>org.quartz-scheduler</groupId>
		<artifactId>quartz</artifactId>
		<version>1.8.5</version>
	</dependency>

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-oracle</artifactId>
            <version>1.8.5</version>
        </dependency>

I’m assuming your application already has a dataSource and a transactionManager defined. Something like:

	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="${driver}"></property>
		<property name="jdbcUrl" value="${url}" />
		<property name="user" value="${username}" />
		<property name="password" value="${password}" />
		<property name="initialPoolSize" value="2" />
		<property name="minPoolSize" value="2" />
		<property name="maxPoolSize" value="5" />
		<property name="checkoutTimeout" value="100" />
		<property name="maxStatements" value="500" />
		<property name="testConnectionOnCheckin" value="false" />
		<property name="maxIdleTime" value="180" />
		<property name="idleConnectionTestPeriod" value="1000" />
	</bean>

	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceProvider" ref="hibernatePersistence" />
		<property name="persistenceUnitName" value="model" />
		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="showSql" value="true" />
				<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
			</bean>
		</property>
	</bean>

	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
		<property name="dataSource" ref="dataSource" />
	</bean>

You will need an dataSource and transactionManager for Quartz to use. Quartz, in order to make sure that multiple servers are not firing the same event, uses the database to keep track of what has executed and what needs to be executed. This allows multiple servers that have the application on it to not fire the same event at the same time. Only one server will fire the job (the server that will do the job is random).

Next we need to set up Quartz to run under Spring. Now, I mentioned Spring Scheduler above. It has it’s one tags, <task>, that work great in single server environments. Anything other than that and you will be using regular Spring bean definitions. There’s quite a bit to the configuration so I’ll go over each piece and then present the whole configuration as one file.

First lets setup the scheduler that will run the jobs for us. This uses the Spring framework SchedulerFactoryBean to create the scheduler that wraps Quartz and runs our jobs for us.

<bean id="scheduler"
	class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">

Next we need to setup some basic configuration parameters to get the system working:

<property name="autoStartup" value="true"/> 
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="waitForJobsToCompleteOnShutdown" value="true"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="dataSource">
	<ref bean="dataSource"/>
</property>
<property name="transactionManager">
	<ref bean="transactionManager"/>
</property>
  • autoStartup – Start the Scheduler as soon as it is instantiated
  • applicationContextSchedulerContextKey – The key in the map that will be passed to our jobs that has the Spring Application Context in it
  • waitForJobsToCompleteOnShutdown – Should we not shut down if a job is in the middle of executing
  • overwriteExistingJobs – If the configuration in this file changes from what Quartz has in the database, should the database values be overwritten
  • dataSource – The dataSource (already defined as a bean somewhere) that should be used for database connectivity
  • transactionManager – The transactionManager (already defined as a bean somewhere) that should be used to retrieve transactions

There are additional properties but they merit more individual attention:

		<property name="quartzProperties">
			<props>
				<!-- Job store -->
				<prop key="org.quartz.jobStore.misfireThreshold">6000000</prop>
				<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.OracleDelegate</prop>

				<prop key="org.quartz.jobStore.isClustered">true</prop>
				<prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>

				<prop key="org.quartz.scheduler.instanceName">ClusteredScheduler</prop>
				<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
				<prop key="org.quartz.scheduler.jmx.export">true</prop>
			</props>
		</property>
  • misfireThreshold – The the number of milliseconds the scheduler will ‘tolerate’ a trigger to pass its next-fire-time by, before being considered “misfired”
  • driverDelegateClass – The class to use to connect to your database instance. I use Oracle. This should be changed to your database type
  • isClustered – Is this a clustered instance. Yes because we are running on more than one server
  • clusterCheckinInterval – How often should things be checked
  • instanceName – The name of this cluster instance
  • instanceId – How will the instances be id’ed? AUTO lets Quartz deal with it
  • jmx.export – Should management beans be exported? I like MBeans so put it as true. This is not required for persistence
		<property name="triggers">
			<list>
				<ref bean="caseArchiveSuspendedJobTrigger"/>
		         </list>
		</property>
  • triggers – The triggers are a list of jobs that need to be executed. More on that in a bit

The last property that needs defined is the factory that will create the Jobs. Spring Scheduler ships with a version that works by creating a new instance of a job each time the job is to be executed. The issue with this is that the job is not in the scope of the Spring application because of this. The Job does have its parameters set but any autowiring or, more importantly, transactions, will not exists. This means that if you job does any database manipulation that requires a commit, it will not work. I have created my own SpringBeanJobFactory that gets around this by creating the job as a regular Spring bean and then using that instance of the bean to execute the job.

		<property name="jobFactory">
			<bean class="mycode.scheduled.SpringBeanJobFactory"/>
		</property>

And the code for the class:

package mycode.scheduled;

import org.quartz.SchedulerContext;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.web.context.support.XmlWebApplicationContext;

/**
 * @author sseaman - mostly a cut/paste from the source class
 *
 */
public class SpringBeanJobFactory 
	extends org.springframework.scheduling.quartz.SpringBeanJobFactory
{

	private String[] ignoredUnknownProperties;

	private SchedulerContext schedulerContext;


	@Override
	public void setIgnoredUnknownProperties(String[] ignoredUnknownProperties) {
		super.setIgnoredUnknownProperties(ignoredUnknownProperties);
		this.ignoredUnknownProperties = ignoredUnknownProperties;
	}
	
	@Override
	public void setSchedulerContext(SchedulerContext schedulerContext) {
		super.setSchedulerContext(schedulerContext);
		this.schedulerContext = schedulerContext;
	}
	
	/**
	 * An implementation of SpringBeanJobFactory that retrieves the bean from
	 * the Spring context so that autowiring and transactions work
	 * 
	 * This method is overriden.
	 * @see org.springframework.scheduling.quartz.SpringBeanJobFactory#createJobInstance(org.quartz.spi.TriggerFiredBundle)
	 */
	@Override
	protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
		XmlWebApplicationContext ctx = ((XmlWebApplicationContext)schedulerContext.get("applicationContext"));
		Object job = ctx.getBean(bundle.getJobDetail().getName());
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);
		if (isEligibleForPropertyPopulation(bw.getWrappedInstance())) {
			MutablePropertyValues pvs = new MutablePropertyValues();
			if (this.schedulerContext != null) {
				pvs.addPropertyValues(this.schedulerContext);
			}
			pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
			pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
			if (this.ignoredUnknownProperties != null) {
				for (String propName : this.ignoredUnknownProperties) {
					if (pvs.contains(propName) && !bw.isWritableProperty(propName)) {
						pvs.removePropertyValue(propName);
					}
				}
				bw.setPropertyValues(pvs);
			}
			else {
				bw.setPropertyValues(pvs, true);
			}
		}
		return job;
	}
	
}

As you can see the code gets the applicationContext and then uses that to retrieve the bean from Spring. This bean will be in any defined transactions and will have all Autowiring already done.

The last steps are to define the trigger and the bean that represents the job. For this we will use more of the Spring Scheduler classes.

	<bean id="caseArchiveSuspendedJobTrigger"
		class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<bean name="caseArchiveSuspendedJob" class="org.springframework.scheduling.quartz.JobDetailBean">
				<property name="name" value="caseArchiveSuspendedJob"/>
				<property name="jobClass" value="mycode.job.CaseArchiveSuspendedJob"/>
			</bean>
		</property>
		<property name="cronExpression" value="0 0 3 * * ?"/>
	</bean>
	
	<bean id="caseArchiveSuspendedJob" class="mycode.job.CaseArchiveSuspendedJob">
		<property name="daysToArchiveSuspended" value="6"/>	
	</bean>

First, create a definition for the type of trigger. Again, mine is Cron based. The CronTriggerBean requires two properties:

  • jobDetail
  • cronExpression

The cronExpression is straightforward. The jobDetail requires some explanation.

The jobDetail uses an instance of the JobDetailBean but not in the way Spring Scheduler intended. The name is set to correspond to the bean id of the bean that represents the actual job. The jobClass is the class of the bean (same as defined in the bean class attribute). This allows the SpringBeanJobFactory to get the actual Spring instance of the bean by using the name while still satisfying the requirements of the JobDetailBean (jobClass is required).

Lastly, we just define our job bean as we would any other bean.

Here is a skeleton version of my job:

public class CaseArchiveSuspendedJob {
    @Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
	public void execute(JobExecutionContext context)
		throws JobExecutionException
	{
            // do something with the db in a transaction
     }
}

And now, here is everything in one file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	default-autowire="byName"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	
	<bean id="scheduler"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
		<property name="autoStartup" value="true"/>
		<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
		<property name="waitForJobsToCompleteOnShutdown" value="true"/>
		<property name="overwriteExistingJobs" value="true"/>
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
		<property name="transactionManager">
			<ref bean="transactionManager"/>
		</property>
		<property name="jobFactory">
			<bean class="mycode.scheduled.SpringBeanJobFactory"/>
		</property>
		<property name="quartzProperties">
			<props>
				<prop key="org.quartz.jobStore.misfireThreshold">6000000</prop>
				<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.OracleDelegate</prop>

				<prop key="org.quartz.jobStore.isClustered">true</prop>
				<prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>

				<prop key="org.quartz.scheduler.instanceName">SgsClusteredScheduler</prop>
				<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
				<prop key="org.quartz.scheduler.jmx.export">true</prop>
			</props>
		</property>
		<property name="triggers">
			<list>
				<ref bean="caseArchiveSuspendedJobTrigger"/>
			</list>
		</property>
	</bean>
	
	<bean id="caseArchiveSuspendedJobTrigger"
		class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<bean name="caseArchiveSuspendedJob" class="org.springframework.scheduling.quartz.JobDetailBean">
				<property name="name" value="caseArchiveSuspendedJob"/>
				<property name="jobClass" value="mycode.job.CaseArchiveSuspendedJob"/>
			</bean>
		</property>
		<property name="cronExpression" value="* * * * * * ?"/>
	</bean>
	
	<bean id="caseArchiveSuspendedJob" class="mycode.job.CaseArchiveSuspendedJob">
		<property name="daysToArchiveSuspended" value="10"/>	
	</bean>
</beans>

As you can see, there is quite a lot setting up Spring and Quartz to easily work within a transaction. I spent way too much time researching this. I hope this helps someone….

Posted in Java, Programming | Tagged , , | 118 Comments

Recursion is as Recursion does

Recursion. It’s one of those questions you see in most interview questions. Usually it’s in the context of something like ‘Calculate Fibonacci numbers’ or something along those lines with the intent of determining if you understand recursion. Its a great question to ask but at the same time the answer itself is actually very wrong if you were going to do it in the real world.

Recursion has it’s place (Sorts, Binary Tree traversal, etc) but don’t just use it because it makes the code smaller. Think about the cost of recursion. Every call:

  • Adds an object to the call stack
  • Allocates more memory
  • Sometimes throws readability right out the window (and down the block, making a left at the mailbox)
  • Eats up CPU time

A coworker of mine (Jay Palat) just recently wanted to dust off his python skills. To do this he decided to code a fun little problem: Get a list of all the even Fibonacci numbers. Now, being a good developer he immediately took to it with recursion like so:

#!/usr/bin/python

"""Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued term"""

def fib(n):
    if n == 0 :
        return 1
    if n == 1 :
        return 2
    return fib(n-1) + fib(n-2)
  
"""for n in range(0,10):
    print fib(n)
"""
item = 0
sum = 0
fib_item = fib(item)
while fib_item < 40000000:
    if fib_item%2==0:
        print "Even item: " + str(fib_item)
        sum = sum + fib_item
    item = item + 1
    fib_item = fib(item)
print "Sum: " + str(sum)
print "Final item : " + str(item)   

Don’t worry about the style or overall approach. The thing to know is that this method, which I dare say most developers would take, uses recursion. In the end this method took, on average, 47 seconds to execute (going up to 40000000).

For each call you have two recursive calls. This means you have at least three entries on the call stack per call, which then has three, and then three…. welcome to recursion. Honestly, we discussed the Big O on this and realized we weren’t that good at Big O and moved on 😉

I then said: ‘Why not do it without recursion? Sure it might not be as cool, might not be as small, but is should use a lot less memory and CPU’.

This is what was coded (stripped down):

old_number = 1
current_number = 1
next_number = 0
sum = 0
while current_number < 40000000:
    print current_number
    if current_number%2 == 0:
        sum = sum + current_number
    next= current_number + old_number
    old_number = current_number
    current_number = next
    
print "Sum :" + str(sum)

And the total execution time for this : 0.027 seconds.

Lets state that again:
Old way with recursion: 47 seconds
New way without recursion: 0.027 seconds

Without the recursion we didn’t have the stack overhead, the additional memory usage, or any of the additional CPU cycles.

So, the next time you think of recursion, think of performance as well. You might even respond in the interview: “Do you want me to just show recursion, or do you want me to make it fast and efficient?”

Posted in Programming | Leave a comment

Websphere, Hibernate, JPA, with a twist of Classpath hell

Problem

Recently I had to take a .war project that utilized Hibernate 3.5 and JPA 2.0 and deploy it in WebSphere 7.0. It has been quite a long time since I worked with WebSphere and was very happy to find that it was very easy to setup and deploy my existing war.

What I didn’t expect was the Classpath mess that was to ensue and the 7 hours of research to find a solution to what appears to be a fairly common problem (but no real solution defined)

You see, WebSphere ships with a copy of OpenJPA. OpenJPA is a JPA implementation that WebSphere provides for use by developers. It just so happens though that the OpenJPA that WebSphere ships with is a JPA 1.0 implementation.

Hibernate 3.5 or > requires a JPA 2.0 implementation. Houston, we have a problem.

No problem you think. I’ve got the JPA 2.0 implementation (hibernate-jpa-2.0-api01.0.0.Final.jar) in my .war’s classpath, so I’m fine. Right?

Wrong. WebSphere puts OpenJPA on the Classpath first, no matter what. You can change the configurations (Parent first/Parent last) and it will still have OpenJPA on the Classpath before the .war file. You’ll start seeing a lot of weird errors like:
java.lang.NoSuchMethodError: javax/persistence/spi/PersistenceUnitInfo.xxxx

If you see the above you have a JPA 1.0/JPA 2.0 issue because of OpenJPA.

Solution

IBM has a Feature Pack (think library upgrade package) for WebSphere to get it to run OSGi and JPA 2.0. Once you install this everything should work fine.

Steps:

  1. Shutdown WebSphere
  2. Download the IBM Install Manager at http://www-01.ibm.com/support/docview.wss?uid=swg24027833 if you don’t already have it.
  3. Start the IBM Installation Manager
    1. Make the Install Manager aware of your WebSphere installation if it isn’t already
      1. Select IMPORT from the main page
      2. Select the installation directory of your copy of WebSphere
      3. Select next for the rest of the steps until finished
    2. Back at the main IBM Installation Manager screen select INSTALL
      1. Select the Feature Pack for OSGi Applications and JPA 2.0
      2. Install the Feature Pack
    3. Once done, exit the IBM Installation Manager
  4. Start the IBM Profile Manager
    1. In the Profile Manager, Select the Server then click AUGMENT
    2. Select the JPA 2.0 and click NEXT then click INSTALL
    3. Exit the IBM Profile Manager
  5. Start up WebSphere
    1. To Verify that the install took:
      1. Go to the web interface for the WebSphere server
      2. Select SERVERS -> SERVER TYPE -> WEBSPHERE APPLICATION SERVERS -> SERVER1 -> RUNTIME -> PRODUCT INFORMATION
      3. You should see ‘Feature Pack for OSGi Applications and Java Persistence API 2.0’
    2. Uninstall your .war, .ear, .etc and reinstall it

The errors should disappear and everything should start working!

Things to note

  • You need to be running WebSphere 7.0.0.9 or greater. If you aren’t, you can’t use the Feature Pack
  • You may need to define the persistence provider in your persistence.xml file. I didn’t have to but I found many sites suggesting that it was the solution (it wasn’t, but it couldn’t hurt). If you want to try it:
    • Add <provider>org.hibernate.ejb.HibernatePersistence</provide> between your <persistence-unit> tags
    • You will notice Hibernate starts up as soon as your app starts in WebSphere. If you haven’t fixed the above error (java.lang.NoSuchMethodError) you will just see it sooner and your app won’t start
Posted in Java, Programming | 19 Comments