顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

2009年5月12日 星期二

JADE/JMS integration Part I- User Scenario

JADE (Java Agent Development Environment) is a mature agent platform. It receives a lots of attention in software agent development paradigm. In this post I will discuss a scenario that using JADE as a basic platform to develop Tel-Gate application. The Tel-Gate is equipped with multiple RFID readers and IP based cameras. The agents in JADE have to communicate with the RFID reader middleware and surveillance system. Then, a fusion process will be execute when the agent receives any signal from both systems.
I list the agent's responsibilities as following:

  1. communicate the surveillance system to get the meta-data which is produced when something appear in the front of the camera. The meta-data from the surveillance is a text message in XML format delivered by JMS.
  2. communicate with RFID middleware (JMS application) to get the RFID signal.
  3. fuse the signal from different devices.
  4. report a situation to backend.
The challenges I have to overcome is list as following:
  1. In JADE how to cooperator with the JMS to get the message from other sub-system.
  2. How to simulate a time domain to fuse the data from difference sub-system.
This project is a benchmark project to compare the capability with SystemJ (which is language the use to perform GALS). I will try to make this program as small as possible.

What will be devliered in this project:
  1. a development project under eclipse.
  2. an ant script that used to execute the build process and execution.
  3. several agents based on JADE will be developed.
  4. a performance result will be reported.
Next post, I will introduce the system architecture of this system.

2009年2月19日 星期四

How to deal with compass SearchEngineException

Well, this problem you may encounter when you start to code your Compass application.
The typical symptom is the system complain the following exception.
javax.servlet.ServletException: org.compass.core.engine.SearchEngineException:
Id with path [company_objid] for alias [Company] not found.
There are several reasons this exception will be through out.
  1. This happens when you are using an old index but made changes to your POJO mappings and you have not yet reindex.[1]
  2. The object's id is null. let find more detail about this in the following code fragment


Company company = new Company();
....
mgr.save(company);
compassTemplate.save(company);//generate company object's index
//this will raise the exception, why?

Well this reason is quite easy. The company object's objid field is null but the objid field is set to be the index id and required by the compassTemplate.
So, if the code fragment changed as following then the exception will be gone.

Company company = new Company();
....
company = mgr.save(company);
compassTemplate.save(company);// now the program can generate company object's index
// with no exception raise.


Reference
  1. http://forum.compass-project.org/thread.jspa?messageID=294009

2009年2月12日 星期四

How to generate Compass index when running unit test

Recently, I post a question to Appfuse mailling list entitle "Compass index not gen when running ActionTest"
Here is the packages I used in my project.

  • Compass 2.1.1
  • Lucene 2.4.0
  • Hibernate 3.3.0.ga
  • Appfuse 2.0.2
After 2 days hard works, luckily I found the solution to solve this problem. The exactly reason that Compass did not generate the index is caused by the Hibernate event not function properly when runing unit test.
Here is the setting in the hibernate.cfg.xml, this setting is used to let Compass can generate index automatically.

<event type="merge">
<listener class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</event>
<event type="post-update">
<listener class="org.compass.gps.device.hibernate.embedded.CompassEventListener"/>
</event>
<event type="post-insert">
<listener class="org.compass.gps.device.hibernate.embedded.CompassEventListener"/>
</event>
<event type="post-delete">
<listener class="org.compass.gps.device.hibernate.embedded.CompassEventListener"/>
</event>

However, for some reason this configuration is not function as it designed under test environment. By the way, there are two hibernate.cfg.xml in Appfuse 2.0.2, one is located in src/main/resources, and the other is located in src/test/resources. In my project these two files are configured with same configuration.
The solution is quite easy, I remove the event handler setting and add the following code in my action.

product=(Product)mgr.save(product); //the manager.save will save the object to database

if(product.getObjid() != null)
compassTemplate.save(product); //using compassTemplate to generate the index manually.

Then the index can produce correctly in test environment.
I list my Compass configuration as following, in case someone need to setup their Compass.

<!--compass-->
<bean id="annotationConfiguration"
class="org.compass.annotations.config.CompassAnnotationsConfiguration">
</bean>

<bean id="compass" class="org.compass.spring.LocalCompassBean">
<property name="classMappings">
<list>
<value>org.itri.istc.model.Product</value>
<value>org.itri.istc.model.Company</value>
</list>
</property>
<property name="compassConfiguration" ref="annotationConfiguration"/>
<property name="compassSettings">
<props>
<prop key="compass.engine.connection">file://d:/compass/imice</prop>
<prop key="compass.transaction.factory">org.compass.spring.transaction.SpringSyncTransactionFactory</prop>
<!-- snowball analyzer provides stemming (so 'monkey' gets 'monkeys', too) -->
<prop key="compass.engine.analyzer.default.type">snowball</prop>
<prop key="compass.engine.analyzer.default.name">English</prop>
<!--
<prop key="org.compass.core.lucene.LuceneEnvironment.Analyzer.ExtendedTypes">CHINESE</prop>
-->
<prop key="compass.property.all.enabled">true</prop>
<prop key="compass.transaction.lockTimeout">300</prop>
<prop key="compass.transaction.commitTimeout">300</prop>
</props>
</property>
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="hibernateGpsDevice" class="org.compass.gps.device.hibernate.HibernateGpsDevice">
<property name="name"><value>hibernateDevice</value></property>
<property name="sessionFactory" ref="sessionFactory" />
<property name="nativeExtractor"><bean class="org.compass.spring.device.hibernate.SpringNativeHibernateExtractor" /></property>
</bean>
<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
<property name="compass"><ref bean="compass" /></property>
<property name="gpsDevices">
<list>
<bean class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">
<property name="gpsDevice" ref="hibernateGpsDevice" />
</bean>
</list>
</property>
</bean>
<bean id="compassTemplate" class="org.compass.core.CompassTemplate">
<property name="compass" ref="compass"/>
</bean>


Reference:
1.http://chuanliang2007.spaces.live.com/blog/cns!E5B7AB2851A4C9D2!389.entry

2008年12月3日 星期三

IText Document Margin Setting Trick

Setting the margin of the pdf is a common task for pdf generation.
I encounter a problem when setting the margin that is the setting always effect on the next page, this means the margin setting in never correct on first page.
After few minutes search on Google, I found if you want to have a correct margin on first page, you should let your margin setting done before you open the document.
Here is the code:

Document document = new Document(PageSize.A4.rotate());
try {
PdfWriter writer =
PdfWriter.getInstance(document, new
FileOutputStream("jTable.pdf"));
document.setMargins(200,200,200,200);
document.open();
// add your pdf content here....
}

2008年11月26日 星期三

How to run a batch file from Java

How to run a batch file from Java, it seems not a very hard problem.

We can find a lot of information from Google. But I still waste two hours to complete this task.
The reason to run the a batch file in Java code is because I want to show up a GattProject user interface when some conditions occured.

Everybody will tell you just using Runtime.getRuntime.exec("YourBatchFileCommand"); then this job is done.
But I tried several times it never works for me.
Finally, I found one tricky thing that we need to put the "cmd /C Start " command before batch file.


Runtime load = Runtime.getRuntime();
Process p = null;
String[] command ={ "cmd", "/C Start D:/projects/GanttProjectTest/ganttproject.bat HouseBuildingSample.gan" };
try {
p = load.exec(command);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

However, this still can't open the GanttProject successfully due to some environment issues such as ClassPath setting.
The solution is copy all the files under GanttProject under your Java Program root folder. In my case the Java class is under "D:/projects/GanttProjectTest/bin".

2008年10月21日 星期二

JADE/SWT Integaration

JADE is a platform to develop agent based application based on Java language.
I used this package in my dissertation. In this post I would like record the integration between JADE and SWT user interface package.
In my agent application, the agent have to catch the user's eye when the agent wants to notify the user who is working arround a PC station.
So, Here is two questions that I have to deal with. The first one is to know the packages that I have to include in my application, the second one is how could I activate the user interface in my agent process.

The first question is easy to solve by using the plugin inspector and plugin depency user interface from eclipse platform.

  1. Find JFace plug-in in the list
  2. Double click on the plug-in then it will show the whole dependencies. We need all this package in the class path.
So, I added the following jar files into my class path
  • org.eclipse.core.commands_3.4.0.I20080509-2000.jar
  • org.eclipse.equinox.common_3.4.0.v20080421-2006.jar
  • org.eclipse.jface_3.4.0.I20080606-1300.jar
  • org.eclipse.osgi_3.4.0.v20080605-1900.jar
  • org.eclipse.swt_3.4.0.v3448f.jar
Then, I have to deal the activation question. In JADE programming, programers have to code their logic in the Behaviour class. Also, an agent can have more than one behaviour class at the same time.
I created a CyclicBehaviour class to linsten the incoming message from other agent. Once a specific message is caught by the agent then a user interface will be activate.
However, I encounter a problem when using the normal Behaviour to activate the SWT/JFace ApplicationWindow like the following code.

The behaviour class is list as following:

private class WorkerReactionBehaviour extends CyclicBehaviour
{


@Override
public void action() {
System.out.println("from worker agent: message collect");
ACLMessage msg = myAgent.receive();
if (msg != null) {
System.out.println("from agent:" + msg.getSender().getName());
String content =msg.getContent();
if(bGuiShow == false)
{
myAgent.addBehaviour(new GuiBehaviour());
gui.notifyUser(content);
}
}
else
System.out.println("worker agent: no message");
//test
//System.out.println("notified user ...");
//gui.notifyUser("test");
block(2000);

}

}

The user interface activate code is list as following:

public class WorkerGuiImpl extends ApplicationWindow implements WorkerGui {
public void show()
{
if(bShowed == true)
return;
bShowed = true;
this.setBlockOnOpen(true);
this.open();
Display.getCurrent().dispose();
}
}//show

The consequence is the agent behaviour will be block when the user interface shows up.
Hence, I have to make the user interface behaviour execute as a dedicated Java thread.
There is a ThreadedBehaviourFactory supported by JADE plateform to wrap the normal JADE behaviour into dedicated Java thread.
Just using the following code to solve the behaviour blocking problem.

ThreadedBehaviourFactory tbf = new
ThreadedBehaviourFactory();
myAgent.addBehaviour(tbf.wrap(new GuiBehaviour()));


Reference
  1. http://www.nabble.com/JADE-SWT-problem-to20093283.html

2008年8月31日 星期日

How to add scripting support in your application

This is a very interesting question, I encountered these days.
Here is the question I was asked. "How to let some behaviors can be changed after system deploy"
The first idea comes to my mind is using late binding design pattern such as factory pattern.
If the factory pattern can be accepted, all I have to do is providing a properties file for customize setting and designing a factory class using a reflect method to load the specified class in the properties file.
Unforunatly, the factory pattern was not accepted, due to the setting of customize environment would be too complex for our user. Hence, I need a customize environement like Visual Basic Application in MS-Office. In Spring framework [1], they do provide the integration with several dynamic languages, such as Ruby, Groovy and Beanshell.
In my system, I hope all the service classes can be customized. Hence, I design a customize service interface with following functions to support the scripting environment.



public interface Action
{
public void setDao(Dao dao);
public void input(Map arg);
public boolean validate();
public void doActionPre();
public boolean doAction();
public void doActionPost();
}
public interface Service
{
public void setXXXXAction(Action action);
}

The second step import the dynamic-language-backed bean's XML schema definition as following:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:lang="http://www.springframework.org/schema/lang"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.0.xsd">

Then define the dynamic-language-backed bean

<lang:groovy refresh-check-delay="60000" id="scriptCustomizeAction" script-source="classpath:CustomizeAction.groovy">
<lang:property name="dao" ref="myDao"/>
</lang:groovy>

<!-- an otherwise normal bean that will be injected by the Groovy-backed Messenger -->
<bean id="myService" class="x.y.MyService">
<property name="xXXXAction" ref="scriptCustomizeAction" />
</bean>



/*CustomizeAction.groovy*/
package x.y;
class CustomizeAction implements Action
{

public void setDao(Dao dao)
{

}
public void input(Map arg)
{

}
public boolean validate()
{
}
public void doActionPre()
{
}
public boolean doAction()
{
}
public void doActionPost()
{
}
}

Here are some points you must be aware in your scripting task[4].

  • The "scope" of the scripting bean is "singleton" in default. It also can be prototype.
  • If your scripting beans do not implements any java interface and you try to inject one scripting bean into another scripting bean as property, your program will throw Exception because springframework cannot use reflection to find the proper set method.
  • If you use groovy as your dynamic language, please don't define more than one class per Groovy source file.
Finally, we need some libraries to enable the dynamic language feature in Spring framework.
  • groovy-1.5.5.jar
  • asm-2.2.3.jar
  • antlr-2.7.6.jar

Reference.
  1. http://static.springframework.org/spring/docs/2.0.x/reference/dynamic-language.html
  2. http://book.javanb.com/Professional-Java-Development-with-the-Spring-Framework/BBL0079.html
  3. http://www.javaworld.com/javaworld/jw-10-2003/jw-1003-beanshell.html
  4. http://scriptlandia.blogspot.com/2007/03/how-to-build-completely-dynamic-example.html
  5. http://www.xeniumhk.com/blog/?postid=54

2008年8月19日 星期二

JUnit4, Spring, and Ant integration

JUnit4[1] provides a set of annotations to help programmer write unit test with more easy way. you can find an introduction documents on the JUint offical web site.
Spring 2.5.5[2] is the latest Spring framework release. In this release, annotation programming support is also an important focus. Spring framework provides an enhanced
class named SpringJUnit4ClassRunner, which is a custom extension of JUnit4ClassRunner.
So, I use this new feature into my test cases and list as following.

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({})
@ContextConfiguration(locations={"/applicationContext.xml"})
public class OrderProcessDaoTest extends AbstractJUnit4SpringContextTests {

@Autowired
private OrderProcessDAO orderDao;

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

@Test
public void testGetNewOrders() {
if(orderDao == null)
fail("orderDao is null");
}
}

I also have an ant script to help me organize the build process.
The version of ant package is 1.7.1
Everything looks perfect, isn't it?

Well, the nightmare came to me when the first time I entered the "ant test-dao".

The ant output report a error said a method testAborted is not found.
then, another error came out said org.junit.internal.runners.JUnit4ClassRunner class not found.

I try to find the solution on the web.
[news.eclipse.platform] Ant junit 4 problem http://dev.eclipse.org/newslists/news.eclipse.platform/msg65786.html
Spring 2.5: Eclipse reports "JUnit4ClassRunner cannot be resolved" http://forum.springframework.org/showthread.php?t=47289
Named TestSuite gives error in JUnit_4.1 used w/Eclipse http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=68&t=001783
Problems running JUnit http://www.nabble.com/Problems-running-JUnit-td6915754.html
... you can find more just using "junit4 testAborted" as keyword to google.

Then I reviewed my enviroment, I found there exist several different version of junit.
In eclipse, junit 4.3 is in the feature plugin folder.
In ant's lib folder, there exists an junit 3.8.jar
In spring's lib folder, there exists an junit 4.4.jar.

In order to pass all the error found by the compiler, I choose spring's junit as my primary junit jar file.
After remove and redirect the classpath to junit.4.4 I solved this problem.

One strange thing I found is the junit.jar in spring framework seems inconsistency from JUnit offical site.
Once, I used the JUnit from spring everything is perfect.

Reference.
1.http://www.junit.org/
2.http://www.springframework.org/

2008年8月7日 星期四

Ant Build File for Windows Service Wrapper

In previous post, I have mentioned the way to run a Java program as a windows service. I like the wrapper tool kit from Tanuki Software very much. However, I encounter some inconvenient situation during the deploy process. For example, the classes build by the IDE have to become a jar file and deploy to the wrapper environment's library folder. It really troublesome when debuging the program. Basically, this is a typical build process problem. Hence, the build tool can tackle this probelm very easily. In Java world, the Apache Ant is the De facto standard of build process execution tool. I develop a small build script to deal with this problem.
Step 1.
Revise the development folder structure.
MYProject
+bin
+wrapperTemplate (download it from Tanuki Software)
+dist
+build
+src

Step 2.
Construct the build script.

<project name="Build&DeployJavaWrapperAp" default="deploy">

<property name="wrapper.dir" location="wrapperTemplate"/>

<mkdir dir="bin"/>

<path id="compile.classpath">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
</path>
<target name="init">

<mkdir dir="build/classes"/>
<mkdir dir="dist"/>

</target>
<target name="compile" depends="init">
<javac srcdir="./src" destdir="build/classes">
<classpath refid="compile.classpath"/>
</javac>
<jar destfile="dist/myproject.jar" basedir="build/classes"/>
<echo>Compilation complete</echo>
</target>
<target name="deploy" depends="compile">
<copy todir="bin">
<fileset dir="${wrapper.dir}"/>
</copy>
<copy todir="bin/${wrapper.dir}/lib">
<fileset dir="dist"/>
</copy>
</target>
<target name="clean" depends="init"/>
</project>

Step 3.
Execute the script.
Just in the Dos command prompt,
in the root folder of the project.
Type: ant (press enter).

This build script help me a lot and I wish this post also can benefit you.

2008年7月23日 星期三

Build Spring & Hibernate based application from scratch

Introduce
I was used to develop my system based on some well designed and integrated framework such as Appfuse. The integrated framework can shorten a lot of development time. So, I never think about build my own application from scratch. Until I starting to code the system for my PHD dissertation.
The major goal of dissertation is to develop a manufacture information platform for distributed mass customization by using inteligence agent. In order to let my agent can inline with my previous development effort, Spring and Hibernate framework integration become my first step to conquer.

Project Layout
Figure 1. shows the project layout. The most important things in Figure 1 is the lib folder.


Figure 1. Project layout
In order to use Spring and Hibernate in my project, I have to import these related jar files into the build path of my project.
The most easy way to test the project layout is correct or not is write a small program to load the Spring configuration.
For Example, create a Java class with a static main function and in the declare area put the following code.


protected final static ApplicationContext ctx;
static{
String[] paths = {"applicationContext.xml",};
ctx = new FileSystemXmlApplicationContext(paths);
}

public static void main(String[] args)
throws IOException
{
}

Well, you will need the Spring configuration file. I named this configuration as ApplicationContext.xml and list as following:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/agentpjm?useUnicode=true&amp;characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="h300"/>
<property name="maxActive" value="100"/>
<property name="maxIdle" value="30"/>
<property name="maxWait" value="1000"/>
<property name="defaultAutoCommit" value="true"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="60"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=${hibernate.dialect}
hibernate.query.substitutions=true 'Y', false 'N'
hibernate.cache.use_second_level_cache=true
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
</value>
<!-- Turn batching off for better error messages under PostgreSQL -->
<!-- hibernate.jdbc.batch_size=0 -->
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>

Put this file in the root of the project folder and run the program, there should be no exception appear in the window, then we can start to add Hibernate configuration and prepare the data access object(DAO).

Reference.
  1. http://www.findjar.com
  2. http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/
  3. http://www.hibernate.org/hib_docs/reference/en/html/session-configuration.html

2008年6月1日 星期日

How to run your java application as windows service

I developed a Java program for RFID reader, the program run as a server to continuous listen to the response from readers. The program was run as console application. So, it need manually startup. This is very troublesome when deploy to commercial environment. So, I want to refactor the program as windows service.
I found Java Service Wrapper is what I need. this package to let your Java application run as windows service.
It provides three kinds of integration. You don't need to code any thing by using WrapperSimpleApp and WrapperStartStopApp. However, I prefer the third method that is implement the WrapperListener. The following section depicts the detail programming model of the using WrapperListener.
We have to do two things before the program can run as windows service.
The first thing is to code, since I choose implementation the WrapperListener interface. So the first thing to do is adding the interface code to my program with following steps.
  1. Add wrapper.jar into you eclipse project as reference.
  2. Implements interface WrapperListener
  3. make your class constructor to private
  4. Register this class to WrapperManager by the following code: WrapperManager.start( new UPortController(), args );
  5. Put your startup logic in public Integer start(String[] arg)
  6. Put your shutdown logic in public int Close(int arg0)
Be aware you have to return a null value when the start up action is success or the wrapper will consider your program fail to startup.

The second steps is setting up the wrapper environment and configuration.
The most easy way to do this is copy the directory structure from the wrapper package.
Here is my file structure.
App
|-bin (the startup bat/sh files and wrapper executable file should inside this folder)
|-lib (your jar files and wrapper.dll)
|-conf (contain only one file named wrapper.conf that described the way to load your class)

Be aware to check your Java class path setting and MANIFEST.MF in jar file.

I list my class path setting as following:
%CLASSPATH%=
.;C:\java\jre1.5.0_09\lib\rt.jar;C:\java\jre1.5.0_09\lib\jsse.jar;C:\java\jre1.5
.0_09\lib\jce.jar;

and MANIFEST.MF content in my jar file.

Manifest-Version: 1.0
Created-By: 1.5.0_09 (Sun Microsystems Inc.)
Class-Path: rt.jar activemq-all-5.0.0.jar commons-lang.jar commons-logging-1.1.jar commons-net-1.4.1.jar spring.jar wrapper.jar
Main-Class: xxx.yyy.zzz.UPortController



Reference
  1. http://wrapper.tanukisoftware.org/doc/english/introduction.html