LONG AGO YESTERDAY

Subscribe to RSS feed

How to install JBoss AS 7 in RedHat

,

Installing Java SE 6
By default, Red Hat 4.1 contains the package java-1.4.2-gcj-compat-1.4.2.0-40jpp.115.
[neodoo@neodoo-02 downloads]$ java --version
   java version "1.4.2"
   gij (GNU libgcj) version 4.1.2 20080704 (Red Hat 4.1.2-44)
   Copyright (C) 2006 Free Software Foundation, Inc.
   This is free software; see the source for copying conditions.  There is NO
   warranty; not even for MERCHANTABILITY or FITNESS FOR A PART ...

First, you have to install the latest Java SE Development Kit (JDK) that you can download from http://java.sun.com/javase/downloads

In this article, I have download Java SE Development Kit 6u16 for Platform Linux x64 (jdk-6u16-linux-x64-rpm.bin).
For install JDK, you have to put execution permissions to the file.
[root@neodoo-02 downloads]$ chmod 755 jdk-6u16-linux-x64-rpm.bin
   [root@neodoo-02 downloads]$ ./jdk-6u16-linux-x64-rpm.bin

You can verify that Java SE is installed in /usr/java/
I verify the Java version of the operating system.
[root@neodoo-00 downloads]# java -version
   java version "1.6.0_16"
   Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
   Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01, mixed mode)

I create dynamic links that let us not to modify scripts if I change Java versions.
[root@neodoo-00 downloads]# mkdir /opt/java
   [root@neodoo-02 downloads]$ ln -s /usr/java/jdk1.6.0_16 /opt/java/jdk

Next, I create the environment variables for Java
[root@neodoo-02 downloads]$ sudo vi /etc/profile.d/java.sh
  
   #
   # Java 
   #
   
   JAVA_HOME=/opt/java/jdk
   PATH=$PATH:$JAVA_HOME/bin
   CLASSPATH=$JAVA_HOME/lib
   LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/i386
   #JAVA_OPTS="-Djava.awt.headless=true"
   
   export JAVA_HOME PATH CLASSPATH LD_LIBRARY_PATH #JAVA_OPTS

I add execution permissions to the file.
[root@neodoo-02 downloads]$ chmod 755 /etc/profile.d/java.sh 

And execute the file for update environment variables.
[root@neodoo-02 downloads]$ . /etc/profile.d/java.sh 

This operation let us to maintain scripts intact and upgrade versions only changing dynamic links.

Installing JBoss AS 7.0.1

Now let's go to install JBoss AS.
Download JBoss AS from JBoss.ORG.
I have choose jboss-as-web-7.0.1.Final (zip format).
Uncompress zip file in /usr/java directory.
[root@neodoo-02 downloads]$ unzip jbossjboss-as-web-7.0.1.Final.zip -d /usr/java/

I create dynamic links that let us not to modify scripts if I change JBoss AS versions.
[root@neodoo-00 downloads]# ln -s /usr/java/jboss-as-web-7.0.1.Final /opt/java/jboss

Create environment variables for JBoss
[root@neodoo-02 ~]# vi /etc/profile.d/jboss.sh
   # 
   # JBoss AS
   #
   
   JBOSS_HOME=/opt/java/jboss
   PATH=$PATH:$JBOSS_HOME/bin
   
   export JBOSS_HOME PATH

I add execution permissions to the file.
[root@neodoo-02 downloads]$ chmod 755 /etc/profile.d/jboss.sh 

And execute the file for update environment variables.
 [root@neodoo-02 downloads]$ . /etc/profile.d/jboss.sh 

I create a new user called jboss and assign this user to jboss directory. Don't start JBoss AS with root user !
[root@neodoo-02 ~]# adduser jboss
   [root@neodoo-02 bin]$ chown -Rf jboss.jboss /opt/java/jboss/

You can start JBoss AS manually.
[root@neodoo-00 bin]# su jboss
   [jboss@neodoo-02 bin]$ /opt/java/jboss/bin/standalone.sh 

By default (due to security reasons) JBoss AS binds only to localhost. If you want to access it via your hostname or IP, then you can edit the JBOSS_HOME/standalone/configuration/standalone.xml to change the "public" and "management" interfaces to point to the hostname of your system:
<interfaces>
  <interface name="management">
    
     <inet-address value="your-hostname"/>
  </interface>
  <interface name="public">
    
     <inet-address value="your-hostname"/>
 </interface>
</interfaces>

Once the server is raised, you can access to it in the url http://your_ip_server:8080

Because application server will be run from non-root user for security respects, we may not start it with port 80 and we have to use local port forwarding in order to forward requests from port 80 to port 8080 as follow: You can insert these lines in the /etc/sysconfig/iptables
iptables -F
iptables -X
iptables -t nat -A OUTPUT -d localhost -p tcp --dport 80 -j REDIRECT  --to-ports 8080
iptables -t nat -A OUTPUT -d Your-IP-server  -p tcp --dport 80 -j REDIRECT  --to-ports 8080
iptables -t nat -A PREROUTING -d Your-IP-server  -p tcp --dport 80 -j  REDIRECT --to-ports 8080

Then we need to save and restart iptables for applying the changes:
# iptables-save > /etc/sysconfig/iptables
# service iptables restart

Please make sure the above changes are saved correctly in /etc/sysconfig/iptables
As we want to Start JBoss on boot we need to create a script to add it a service so it would start at boot up.
we will put it in /etc/init.d/jboss on run level 3 and 5:
-------------------------------------------------------------------------------------------------------
#!/bin/bash
### BEGIN INIT INFO
# Provides:          jboss
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start/Stop JBoss AS v7.0.0
### END INIT INFO#
#source some script files in order to set and export environmental variables
#as well as add the appropriate executables to $PATH
[ -r /etc/profile.d/java.sh ] && . /etc/profile.d/java.sh
[ -r /etc/profile.d/jboss.sh ] && . /etc/profile.d/jboss.sh
MYSERVERIP="192.168.42.188"
MYPORT="9999"
case "$1" in
    start)
        echo "Starting JBoss 1.6.0_20-b02"
        su - sokan -c   "${JBOSS_HOME}/bin/standalone.sh&" > /dev/null 2>&1
    ;;
    stop)
        echo "Stopping JBoss 1.6.0_20-b02"
        su - sokan -c "${JBOSS_HOME}/bin/jboss-admin.sh --connect controller=$MYSERVERIP:$MYPORT command=:shutdown" >/dev/null 2>&1
       # su - sokan -c  "${JBOSS_HOME}/bin/jboss-admin.sh --connect  command=:shutdown"
    ;;
    *)
        echo "Usage: /etc/init.d/jboss {start|stop}"
        exit 1
    ;;
esac
exit 0
-------------------------------------------------------------------------------------------------------------------------

Then we need to execute following commands:
# chmod 755 /etc/init.d/jboss
# cd /etc/rc.d/rc3.d
# ln    -s   ../init.d/jboss     S97jboss
# cd   /etc/rc.d/rc5.d
# ln   -s   ../init.d/jboss    S97jboss


Refrence:
How_to_install_JBoss_AS_in_CentOS_/_RedHat_/_Fedora

Using Linux Cron to execute oracle sqlscripts

, ,

First create an script file in '/home/oracle' like:
[oracle@devserver ~]$ cat dailyScript.sql
column sd new_value sd
select to_char(sysdate, 'YYYYMMDD', 'NLS_CALENDAR=PERSIAN') sd from dual;
set pages 0;
set pagesize 0;
set echo off;
set feedback off;
set termout off;
set linesize 250;
set trimspool on;
spool /home/oracle/my_daily_report_&sd..log
select to_char(sysdate, 'Dy DD-Mon-YYYY HH24:MI:SS', 'NLS_CALENDAR=PERSIAN') 
as "Current Time" from dual;
select * from myTable;
spool off

Note1: SPOOL followed by file_name begins spooling displayed output to the named file.

Note2: The two first lines are used to name spool file with report day!

Next create shell script file to run sql script file:
[oracle@devserver ~]$ cat myReport.cron
#!/bin/bash
ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
export ORACLE_HOME
ORACLE_SID=orcl
export ORACLE_SID
USER='OracleUser'
PASS='OraclePassword'
$ORACLE_HOME/bin/sqlplus <<EOF
${USER}/${PASS}
@/home/oracle/dailyScript.sql
exit
EOF

 

Note: oracle_home, oracle_sid variables must be defined and sqlplus command called with full path.

Now, we define new cron job by 'crontab -e' in console and make it look like this[to learn more about crontab type 'man crontab']
[oracle@devserver ~]$ crontab -e
30 23 * * * /home/oracle/myReport.cron

Instead of the first five fields, one of eight special strings may appear:
string         meaning
------         -------
@reboot        Run once, at startup.
@yearly        Run once a year, "0 0 1 1 *".
@annually      (same as @yearly)
@monthly       Run once a month, "0 0 1 * *".
@weekly        Run once a week, "0 0 * * 0".
@daily         Run once a day, "0 0 * * *".
@midnight      (same as @daily)
@hourly        Run once an hour, "0 * * * *".

An example of crontab format with commented fields is as follows:
# Minute   Hour   Day of Month       Month          Day of Week  Command
# (0-59)  (0-23)     (1-31)    (1-12 or Jan-Dec)  (0-6 or Sun-Sat)
    0        2          12             *               0,6     /usr/bin/find

Circular Relationship in Web Service

, , ,

If you have been working with Web Services before, you have probably drawn the conclusion that they are intrinsically difficult! But using JAX-WS and EJB3 you may have your Web Service in no time by adding a few annotations like @WebService and @WebMethod. But there are always nightmares while developing complicated solutions. Circular relationship was our nightmare with the lovely Web Service!

Suppose that you have a bidirectional relation between two classes. For example class MySample1 has an instance of MySample2 and vice versa. Like this:

public class MySample {
private MySample mySample;

public MySample getMySample() {
return mySample;
}

public void setMySample(MySample mySample) {
this.mySample = mySample;
}
}

Now if we want to have a Web Service method as:
@Stateless(name = "MySampleEJB")
@RemoteBinding(jndiBinding = "MySampleRemote")
@Remote(MySampleRemote.class)
@WebService
public class MySampleBean {
    @WebMethod
    public MySample getMySample(){
        MySample a = new MySample();
        MySample b = new MySample();
        a.setMySample(b);
        b.setMySample(a);
        return b;
    }
}

It ended up to following exception:
org.jboss.ws.WSException: javax.xml.ws.WebServiceException: javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.SAXException2: A cycle is detected in the object graph.

I can’t imagine how this situation could be serialized and it is somehow reasonable to get the circular exception but the Boss wants this relation and nothing is impossible! The problem is also mentioned here.

Well I found a little weird solution for this problem but at least it was suitable for us. First of all you should know that there is an interface to handle circular relationship in JAXB named 'CycleRecoverable' so we may return null as object when has circular problem! But it is not the end of story if you clone the mySample instance in the setter method everything works fine somehow!
public class MySample implements Serializable, CycleRecoverable, Cloneable{
    private MySample mySample;

    public MySample getMySample() {
        return mySample;
    }

    public void setMySample(MySample mySample) {
        try {
            if(mySample != null)
                this.mySample =(MySample) mySample.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
    public Object onCycleDetected(Context context) {
        return null;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Well in client side you will get an instance of ‘MySample’ as follow:

The chain of references is broken but who cares? I could load a tree structure using this method via web service with no problem.

My Experinece with Ubuntu 8.10

Getting really bored with Windows XP I decided to try Ubuntu Linux 8.10 a couple days ago. As a newbie to Ubuntu I really wondered when I saw all hardwares worked perfect after installation and I didn't even setup network connection!
Well here's what I have done with my Ubuntu 8.10 until now:

Persian Fonts:
Ubuntu supports pension language and you can simply add Persian keyboard layout from System → Administration → Language Support but the default Persian fonts are not sufficient and the Persian websites are not look as they should. So I found this and this for installing Persian fonts on my Ubuntu.

sudo apt-get install ttf-farsiweb
sudo apt-get install xfonts-intl-arabic
sudo apt-get install xfonts-intl-european
sudo apt-get install xfonts-intl-phonetic
sudo apt-get install gsfonts-x11
sudo apt-get install msttcorefonts
wget -c http://voxel.dl.sourceforge.net/sourceforge/fpf/fpf.zip
wget -c http://hezardastan.sourceforge.net/persianfonts/tahoma.tar.gz
wget -c http://hezardastan.sourceforge.net/persianfonts/bfonts.tar.gz
sudo mkdir /usr/share/fonts/truetype/ttf-persian-fonts
sudo unzip fpf.zip -d /usr/share/fonts/truetype/ttf-persian-fonts
sudo tar zxvf tahoma.tar.gz -C /usr/share/fonts/truetype/ttf-persian-fonts
sudo tar zxvf bfonts.tar.gz -C /usr/share/fonts/truetype/ttf-persian-fonts
sudo fc-cache -f -v


Turning on Clear Type Mode:
I like Clear Type mode in windows it makes fonts very smother. Can I have it in Ubuntu Linux? Yes! Here it is.

Spider Card Game and Golha Radio!:
My mother is another user of my desktop computer and she like to play “Spider” card game while listening to Golha Radio and I had to prepare her game in Ubuntu.
Firstly I found PySol and installed it via Synaptic Package Manager but although it has so many card games, I couldn't find a game exactly like Windows Spider! Hence I tried installing kpat (KPatience) and it was exactly the thing that made switching to Ubuntu possible! Anyways after playing with other fantastic Ubuntu games my mother doesn't play Spider anymore!!!

Installing Tor:
Its time to surf Internet freely!! And it was very straightforward: Install 'tor', 'privoxy' and 'torbutton-extention' from repository. Then you should configure privoxy as follow:
sudo gedit /etc/privoxy/config

Add the following line at top of the file (don't miss the dot at the end of line):
forward-socks4a / 127.0.0.1:9050 .   

Search for 'logfile logfile' and comment out the line.
Search for 'jarfile jarfile' and comment out the line.
After saving file restart the Privoxy service:
sudo /etc/init.d/privoxy restart

Now restart Firefox and you will see a red text in bottom right corner of Firefox saying:
Tor Disable. Enable tor by clicking text, it should turn to green and say Tor Enabled. Now you can surf the web freely smile

Problem with HP laserJet 1020:
The other day I noticed that my printer which is HP LaserJet 1020 doesn't work! I am sure it was working after installing Ubuntu but maybe after updating Ubuntu something made it ot of order! The problem was that it accepted print jobs and cleared them but nothing would happened! So I tried whatever came to my mind like testing it by another computer with windows XP (worked), reinstalling CUP, changing USB port etc. Nothing worked but google again proved me the first thing for solving a problem should be always googling!
http://foo2zjs.rkkda.com/ emphatically says not to use the foo2zjs driver from the Ubuntu repository. Instead, they want you to download from their site and compile from source. So I did it and my printers started printing again smile

Share Printer on Network:
I wanted to share my Ubuntu printer so that my notebook with XP windows could print to it. And there was no problem at all: https://help.ubuntu.com/community/NetworkPrintingFromWinXP

Set Static IP Address:
Well lets set a static IP address for Ubuntu because it has shared the printer. Oops NetworkManager that provide so simplified Internet connection for me has a known problem with static IP address! Settings made in NetworkManager will not be applicable at the next restart. Ultimately if you assign a fixed IP address in NetworkManager, this setting will be forgotten the next reboot. There is a solution for it but it was not that much important for me so I just forget about it! Hopefully it will be fixed soon...

Merging Partitions in Ubuntu 8.10:
Getting addicted to Ubunto, I wanted to delete windows partition and add it to Ubuntu partition so I used GParted with live CD as GParted doesn’t resize mounted partitions so I had to first swapoff swap partition by “sudo swapoff –a” it is also possible by right clicking on swap partion in Gparted and choosing swapoff. Then deleting swap partion, Coping Ubuntu portion to have:
Ubunto Partition | unallocated space | Swap Partition
Then I could expand the Ubunto Partition.

Restarting Grub
Unfortunately after merging partitions the Grub returned error at start up so I tried restoring Grub from live CD by helping from here.

And now life is beautiful! I really like Ubuntu and I really like when I feel everything is under control!




JNIEasy Hello World Sample

JNI (Java Native Interface) is one of really difficult technologies in Java. Firstly you should know C/C++ very good and then you should handle many things such as errors, memory, configurations etc. Wishing to find an alternative I stumbled upon JNIEasy. With JNIEasy your way to integrate Java and C/C++ is more straightforward.
Bellow follows my Hello World sample of mapping a Java class with its C++ equivalent.
Well I want to have an array of bytes shared between C++ and Java. First of all I have to create a wrapper:
public class MyCPPClassOnDLL {
     protected int virtualTable; // the C++ class has a virtual method     
     public MyCPPClassOnDLL() // mandatory (is not native)
     {
     }
     public static native void destroy(MyCPPClassOnDLL obj);  
     public native byte[] getValue(int index);
     public native void setValue(byte[] test,int index) ; 
} 

As you see we have only method declaration here and the implementation is in C++ side as follow:
dll.h:
#include "JNIEasy.h"
class DLLEXPORT MyCPPClassOnDLL
{
protected:
    char** m_value;    
public:
	
    virtual ~MyCPPClassOnDLL();
    static MyCPPClassOnDLL* __stdcall create();
    static void __stdcall destroy(MyCPPClassOnDLL* obj);
	
    void __stdcall setValue(char* test,int index);
	
    char* __stdcall getValue(int index);

};

dllmain.cpp:

#include "dll.h"
#include <stdio.h>
#include <stdarg.h>
#include <iostream>
#include <cstdio>

using namespace std;

char debugMsg[256];
char *buffer;
char input[256] = "";
unsigned long inSize;
unsigned long msgSize;
bool running = true;


#define PAUSE system("PAUSE")

MyCPPClassOnDLL::~MyCPPClassOnDLL()
{
   m_value = new char*[2];
}

MyCPPClassOnDLL* __stdcall MyCPPClassOnDLL::create()
{
    return new MyCPPClassOnDLL(); // may be an inherited class
}

void __stdcall MyCPPClassOnDLL::destroy(MyCPPClassOnDLL* obj)
{
    delete obj;
}

void __stdcall MyCPPClassOnDLL::setValue(char* value,int index){     
     m_value[index] = value;
}     


char* __stdcall MyCPPClassOnDLL::getValue(int index){
       return m_value[index];
}

You should make a DLL from them.
The sad part is creating XML hell to explain how to bind methods of Java class to DLL libraries:
<?xml version="1.0" encoding="UTF-8"?>

<jniEasyEnhancer version="1.1"
    xmlns="http://www.innowhere.com/jnieasy/enhancer"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.innowhere.com/jnieasy/enhancer
        ../../../schemas/JNIEasy.enh.xsd">

    <package name="ir.org.kia.common.jniObjects">
        <imports/>
        <class name="MyCPPClassOnDLL" type="class"
                libraryPath="DevShareValue" >

            <constructor onLibrary="true"
                    nativeName="gcc:_ZN15MyCPPClassOnDLL6createEv">
            </constructor>

            <method name="destroy" onLibrary="true"
                    nativeName="gcc:_ZN15MyCPPClassOnDLL7destroyEPS_"
                    params="MyCPPClassOnDLL">
            </method>

            <method name="setValue" onLibrary="true"
                    nativeName="gcc:_ZN15MyCPPClassOnDLL8setValueEPci">
                <return class="void"/>
                <params>
                    <param class="byte%5B%5D" />
                    <param class="int" />
                </params>
            </method>
            <method name="getValue" onLibrary="true"
                    nativeName="gcc:_ZN15MyCPPClassOnDLL8getValueEi">
                <return class="byte[]"/>
                <params>
                    <param class="int"/>
                </params>
            </method>
        </class>
    </package>
</jniEasyEnhancer>

Well you have to find nativeName in DLL file in order to map it to Java method. And
‘PEDUMP’ will do it for you. You have to execute a command like
‘pedump DevShareValue.dll >pedump_DevShareValue.txt’ and then under ‘exports table’ part of generated txt file, you will find native names.
There are also some other xml files for pointing to the locations.
Now it’s time to load stuff:
public class JNILoader {
    private static JNILoader ourInstance = new JNILoader();

    public static JNILoader getInstance() {
        return ourInstance;
    }

    private JNILoader() {
        final ResourceBundle theResourceBundle = ResourceBundle.getBundle("jni");
        JNIEasy jniEasy = JNIEasy.get();
        jniEasy.setFeature("jnieasy.license.dir",theResourceBundle.getString("jnieasy.license.dir"));
        jniEasy.setFeature("java.library.path",theResourceBundle.getString("java.library.path"));
        jniEasy.load();
        try {
            jniEasy.getEnhancer().enhance(
                    new URL("file:"+theResourceBundle.getString("enhancer.path")),
                    theResourceBundle.getString("out.path"));
        } catch (MalformedURLException e) {
            e.printStackTrace();  
        }

    }
    public void initMacros()
    {
        NativeTypeManager typeMgr = JNIEasy.get().getTypeManager();
        DynamicLibrary dll = JNIEasy.get().getDLLManager().get("DevShareValue");
        long address = dll.getAddress("?create@MyCPPClassOnDLL@@SGPAV1@HH@Z");
        if (address != 0)
            typeMgr.defineMacro("MSC");
        else
            typeMgr.defineMacro("gcc"); // MinGW or cygwin gcc
    }

}

An at last you have access to C++ class via Java:
public class Main {
    public static void main(String[] args) {
        JNILoader.getInstance().initMacros();
        // Calls create() C++ method. New object is already native
        MyCPPClassOnDLL obj = new MyCPPClassOnDLL(); 
        obj.setValue("Hello ".getBytes(),0);
        obj.setValue("World!".getBytes(),1);
        System.out.println("Hello World from C++: " + 
                new String (obj.getValue(0))+
                new String (obj.getValue(1)));
    }
}


What is best Seam pattern?

As far as I know we have five options for implementing Seam components:
  • Backing Beans
  • Stateful Session Beans
  • Entity Beans
  • Message-Driven Beans
  • Stateless Session Beans

The three last items fundamentally are not very good choices because of stateless nature of SLSBs and MDBs and of course Entity Beans are not good place for writing business logic!
So the question is what are pros and cons of using SLSB VS Backing Beans plus session façades?

Pros:
  • Simpler classes design because you can bridge the JSF component model with EJB component model.
  • Transactions are handled.
  • You have instance pooling.

Cons:
  • SFSBs are heavy components I know they are very optimized in EJB3 but they are still heaver than POJOs.
  • Using SFSB as component makes the classes design simple but useful for hello world applications! In a real application if you put all business logic in one SFSB it will end up with a huge class!! For preventing it you may decide to separate business into many SFSBs but is it wise to have many costly SFSBs for each user? You may use some Stateless Session Beans for servicing your SFSB so why you didn’t use POJO and many SLSB services?
  • I can’t imagine what is the use of having transactions handled in a component while we can decuple business components like any other rich client application?

    Update:
    Well now I can see the usage of Stateful Session Beans in Seam. Suppose you have a method like this:
    public void doSomething(){
    1.do some db related CRUD;
    2.do some UI related staff;
    3.do some db related CRUD;
    }
    And suppose that the order of above tasks is important and on the other hand you want to have all of them in one transaction. Although it is possible to put transaction in a SLSB but it is definitely simpler to have a SFSB as a component especially in transactional or workflow based situations.

13949712720901ForOSX

,

EJB-to-Client Notification

, , ,

A few days ago I asked a friend of mine -who is Java addicted- about EJB-to-Client Notification. I was wondering why EJB doesn’t support events for notifying swing based clients of the changes i.e. updates, deletes etc.
His answer was that I have to use JMS but this is not acceptable because I am talking about an easy to use event driven approach that handles the problem of locating clients and so on. I want to fire an event in the server and the EJB Container notifies all clients.
Anyways even using JMS there is no clear approach for implementing this feature. It seems that this is the problem addressed by the ’Observer Design Pattern’. According to this pattern one approach is for every client to query the server periodically but this can be computationally wasteful. Another solution is for the server to be designed knowing its clients. But giving the server knowledge about its clients breaks the classic client-server model and this approach also doesn’t recommend.

So I think the best solution is adding a Broker i.e. a “reference repository” to the EJB Container which grabs the location of clients as they connect to it (Note that I’m talking about desktop applications).

Distributed computing with Terracotaa

, , ,


One year without any post!!! So how can I blame Behrang for calling me lazy ass?  sad
Anyways I want to share my experience using Terracotta for clustering POJO applications. First of all I should say that the idea behind Terracotta is really nice which is adding a VM like layer under JVM for sharing objects or replicating change between them. Actually I wanted to prepare a cluster for implementing distributed computing, something like this. After googling for finding easy to implement general solutions, I found Master/Worker pattern and it’s implementation. So I tried to write a sample that has workers with various tasks, which is PI calculator with two Workers that can be run parallel. Unfortunately my sample performance is not good at all in compare of RMI (PI implementation with RMI also is attached). But there are some problems in my code, firstly I have always performing two parallel operations and secondly Terracotta has some startup overhead that is not present in other solutions like RMI and thirdly my program has not a timer for measuring the actual start and stop and lastly my sample is entirely CPU bound and maybe it doesn’t show significant difference between Terracotta and RMI for this particular use.
Unfortunately I hadn’t time to accomplish a better distributed parallel sample with better and newer Master/Worker implementation
For now I can only say go ahead Terracotta and GOOD LUCK!!
PI with Terracotta
PI with RMI

problem in charWidth method of FontMetrics

, ,

There is a problem in charWidth method of FontMetrics class when using it for finding the width of a Unicode character in JDK1.5. Although it works correctly but in JDK1.5 it’s more than 10 times slower than JDK1.4. I used both charWidth(int codePoint) and charWidth(char ch) methods and the result is same.
I have used many features of JDK1.5 in my project and it’s very hard to switch back to JDK1.4 and now it works very slowly.sad