This tutorial will walk you through the entire process of making a
POJO application that works on the wire.
Although the code is extremely simple, the same principles apply to
any code.
Start up your IDE, (we use Netbeans) and lets begin...
MAKING A POJO APPLICATION
- Make a General Java Application Project and call it
(Project Name) WalkThru.
- Call the main class CDUnit
- Click FINISH
In your project you will see it creates a standard package
(folder) called walkthru. In this demo we are going to place
all the code under that.
- Right click on the folder walkthru, select new Java
Class and call it MyService, click FINISH.
- Right click on the folder walkthru, select new Java
Class and call it MyClient, click FINISH
So now in your project under the walkthru folder you
should see 3 classes. CDUnit, MyClient and MyService.
- Replace the code in each of those classes with what is listed
below.
|
package
walkthru;
public
class CDUnit {
public void start(){
MyService myService = new
MyService();
MyClient myClient = new MyClient();
myClient.setService(myService);
myClient.getServiceString();
}
public static void main(String[]
args) {
new CDUnit().start();
}
} |
package
walkthru;
public
class MyClient {
private MyService myService;
public void setService(MyService
myService){
this.myService = myService;
}
public void getServiceString(){
System.out.println(myService.getString());
}
}
|
package
walkthru;
public
class MyService {
public String getString(){
return "Hello Out
There";
}
}
|
- Compile the WalkThru project and then right click on the
CDUnit and run it.
What you should see is the "Hello Out There" message in
you're IDE's system out tab.
The CDUnit simply initializes the two classes, passes the Service
class into the Client class, and then displays the string.
What we have done so far is create a very simple Stand Alone
POJO program.
DECOUPLING THE CLASSES
We know that ultimately these 2 classes, the client, and the
server, will run on the wire, so what we have to do is decouple
them.
We do not have to decouple every class in a POJO application,
only the ones that are manipulated in the CDUnit.
Later you will see that the CDUnit lets us decide where we want the
classes to run.
In other words the client and server classes are in the CDUnit
because ultimately we are going to start the server class inside
Harbor, and the client class on a remote machine.
We'll get to that later.
- Right click on the folder walkthru, select new Java Interface
and call it I_MyClient, click FINISH
- Right click on the folder walkthru, select new Java Interface
and call it I_MyService, click FINISH.
- Replace them with the code below.
|
package
walkthru;
public
interface I_MyClient {
public void
setService(I_MyService myService);
public void getServiceString();
}
|
package
walkthru;
public
interface I_MyService {
public String getString();
}
|
Almost done...
- Replace MyClient, MyService and CDUnit classes with the
following
|
package
walkthru;
public
class MyClient implements I_MyClient{
private I_MyService myService;
public void
setService(I_MyService myService){
this.myService = myService;
}
public void getServiceString(){
System.out.println(myService.getString());
}
}
|
package
walkthru;
public
class MyService implements I_MyService {
public String getString(){
return "Hello Out
There";
}
}
|
package
walkthru;
public
class CDUnit {
public void start(){
I_MyService myService = new
MyService();
I_MyClient myClient = new
MyClient();
myClient.setService(myService);
myClient.getServiceString();
}
public static void main(String[]
args) {
new CDUnit().start();
}
}
|
- Compile the WalkThru project and then right click on the
CDUnit and run it.
As you begin to understand the concept, you will not do it in 2
steps, its done here to allow one to study how a class changes when
its decoupled with an interface. As you can see, giving a class an
interface is very simple.
Well, congratulations, that's it, done... this application
will run inside Harbor. Before we deploy it, lets just examine what
you have actually made.
- An application that can run in Harbor, one where the client
will be started remotely, and it will talk to the server
side in Harbor.
- Because we have decoupled the server side from the client
side, this service could also be used by any other client
application in Harbor. So in effect it has become a library
for use by other applications.
- You could now phone your friend working at the North Pole, who
happens to be writing a normal POJO application and say to him,
"OK its done you can use this service". He will
include a few lines of code, and what you have done here, will
work there as well.
- You could also use this service in a remote servlet container
and serve it up to the web.
DEPLOY YOUR APPLICATION
Before we deploy it, we need to familiarize ourselves with a few
things...
If you look in your file manager for the project, you should see a
folder structure like this for Netbean projects... \WalkThru\dist
In there you should see your compiled project called WalkThru.jar
Now locate the repository, you should find this under... \Tomcat
5.5.23\webapps\harbor\HarborRepository
- Under that HarborRepository folder create another one called
WalkThru, i.e. it will now be
\Tomcat 5.5.23\webapps\harbor\HarborRepository\WalkThru
- Copy WalkThru.jar to the \Tomcat 5.5.23\webapps\harbor\HarborRepository\WalkThru
folder
Its inside Harbor now, but we have to tell Harbor to look at it,
this assumes Harbor is running and we have dropped a new project in,
so to make this happen...
You will see your WalkThru.jar is now in the Harbor
classpath, and that means Harbor will serve this application.
MAKE YOUR SHIP
We now have our application inside Harbor, ready to
be used, so what we are going to do now is make a Ship that can use
that application.
Ships are what other programs use, so that they can access the
application in Harbor. A Ship that runs as a executable Jar is
really just one variation that allows your customer to use the
application in Harbor easily. That's what we going to make now.
Now watch carefully because its this relationship
between normal POJO code, and the container specific API,
that made us party for a week.
- Make a General Java Application Project and call it
(Project Name) WalkThru_Ship.
- Deselect the main class name, so that the project
does not make any classes.
- Click FINISH
This is a little tricky, and remember to hold the
CTRL key down when you do it...
In Netbeans arrange the folders so you can see both projects.
-
Copy the walkthru folder from the WalkThru
project to the WalkThru_Ship project. You do this by selecting
the folder in the one project, dragging it down to the Source
Packages in the Ship project (pressing ctrl) and letting go.
-
Now delete the MyClient and MyService classes in
the Ship project. This then leaves you with the Interface
classes and the CDUnit.
-
Right click on the libraries folder,
select Add Jar, navigate to your unpacked download and
select harbor_client_lib.jar
Ok now all we need to do is decide what we want to
run, where. We want the client class to run on the client, and the
server class to run in Harbor.
|
package
walkthru;
import
kewlstuff.harbor.client.Vessel; //Added ref to library
public
class CDUnit {
private Vessel vessel = null; //Added
public CDUnit() {
//We tell this code where our application server is
String harborUrl =
"http://localhost:8080/harbor/service";
vessel = new Vessel(harborUrl); //get a vessel from the harbor
}
public void start(){
//I_MyService myService = new
MyService();
//We make the service run *on*
Harbor
I_MyService myService = (I_MyService)vessel.loadRemoteClassInst(I_MyService.class,"walkthru.MyService");
//I_MyClient myClient = new MyClient();
//We make the client run *here*
(remotely)
Class uiApp =
vessel.getRemoteClass("walkthru.MyClient");
if(uiApp != null){
I_MyClient myClient = (I_MyClient)vessel.newInst(uiApp);
myClient.setService(myService);
myClient.getServiceString();
}
if(myService != null)
vessel.releaseRemoteClassInst(myService);//Release remote
class
}
public static void main(String[]
args) {
new CDUnit().start();
}
}
|
Notice that all we really doing is replacing the NEW
sections, i.e. the instantiation, with the Harbor API. Its almost identical
to the original CD unit.
Well done you have just put the application
on the wire, if you compile that and run it... it will display the
message, just like the original application.
Only difference now is that if you put Tomcat online, change the URL
in this code to point at the Harbor server, whoever runs this Ship,
no matter where they are, will see it work as well.
You can reference the Ships article to see how to
start this from the browser, we not going to do that because this
code writes to system out, and you wont see anything.
Note that a Ship is just code that one can start by
clicking on the Jar. So whoever does that will see it run, but the
thing to note is that its just some very simple code.
So if you took this simple code, say just the server section, and
put it in a servlet container running in another country, yes, that
would use this server object as well.
With just a very simple decoupling design pattern,
what we call coherent diffusion not only does any application
we make become wire friendly, the parts that we have decoupled
become web services and libraries for any other POJO application,
anywhere in the world.
Its webstart, EJB, and web services, all derived
from a simple POJO application.
Also note that the original POJO code has not been interfered with
by Harbor, so if it was a game library, its still a game library
that can be used in other POJO applications. It gives new meaning to
code once, run anywhere.
Enjoy your party...
==============================
|