D:\DEV\PROJECTS\Harbor_Tests\src\harbor\test\testGettingRemoteClasses.java
/*
 * testClassLoading.java
 */
package harbor.test;
import java.lang.NoClassDefFoundError;
import harbor.interfaces.*;
import kewlstuff.harbor.client.Vessel;

/**
 *
 * @author Johnny Kewl
 * TEST 1
 * This test GETS classes from a remote harbor and runs them on the local machine.
 */
public class testGettingRemoteClasses {
    private Vessel vessel = null;
    
    /** Creates a new instance */
    public testGettingRemoteClasses() {
        String harborUrl = "http://localhost:8080/harbor/service"; //location of container harbor
        vessel = new Vessel(harborUrl); //get a vessel from the harbor
        vessel.verboseVessel(true);// watch the class loading process in system.out, for debugging        
    }
    
    /** Gets a remote class and runs it */
    public void runTest(){
        Class msgTest = vessel.getRemoteClass("harbor.classContainer.MsgTest");//load a class from the harbor
        if(msgTest != null){// if class is null check the url and make sure tomcat is running

            I_MsgTest i_MsgTest = (I_MsgTest)vessel.newInst(msgTest);//can have many instances of a single class (its just like new)           

            try{//run a function
                System.out.print(i_MsgTest.getTheMsg() + "\n"); 
            }catch(NoClassDefFoundError e){System.out.print("NoClassDefFoundError normally because DEPENDENT class not found " + e.getMessage()); return;}
        }        
    }
}

/* Notes:
 * GETS... means the class bytes are read from the remote server, and the class is loaded
 * locally. So other than the delivery of the class to this local client, the
 * server does no work. Because it then sits in your client side classloader, any
 * further use of the class, does not disturb the server at all.
 * Its a fantastic way to deliver applications, or parts of applications to a remote
 * client... and one can do it incrementally. For example you can do just enough to
 * quickly get the client GUI running, and only if a class is needed, is it loaded
 * from the server. The client does not notice big downloads, and the important
 * thing to understand is that once that class is loaded, its as fast as if the
 * application had been installed on the machine.
 * 
 * Its the best of both worlds, clients tend to be overpowered, and typical application
 * servers burdened trying to run everything, this allows one to still control the code
 * but not run it all on the application server.
 *
 * And to really blow your sox off, you will see that you can use inter-dependent classes
 * between client and server. So for example you can take your whole POJO application,
 * drop it into the server, and then decide to run one class on the client, and the other
 * (in the same application) on the server. Even though one class in your application
 * is now actually running 2000km away from the other class in your application, and they
 * depend on each other... the software will work as a single application.
 * Will smart design, a typical organization will never need a huge application
 * server cluster. Incidentally, because one can cluster Tomcat behind Apache JK, it means
 * that naturally you can cluster Harbor, however this has very little to do with load, because
 * one can simply run many Tomcats with Harbors as well, clustering in the Harbor context is
 * more about redundancy, ie if a machine breaks, the app keeps running.
 *
 * Some technical comments....
 * If any of the supporting dependent classes can be found on the local system they will
 * be loaded locally.
 * For example MsgTest uses the class Msg... so when you (getRemoteClass) MsgTest, the system
 * will try get msgTest AND Msg which in most cases is what you want.
 * BUT if Msg is LOCAL, it wont come from the remote system.
 * Maybe you want that, maybe not... it simply gives you even more control over how you
 * want to deliver classes. For example, some can be on the installation CD, some can be on
 * the server but run locally, and some can be on the server and run remotely.
 *
 * NB - Understand that classes in the harbor repository should NOT be in the Java Class Path
 * Its an independent container outside of your PCs containment. To install a normal 
 * POJO library jar, and its dependencies, you just drop them into the repository folder
 * of the server... thats it. You do not put them in the system class path.
 * 
 * Now other things also happen... Indirectly MsgTest is also an Object, so this will
 * be loaded from the local system because its a java class, thats how it should be.
 *
 * BUT NB NB.. if the system cant find the I_MsgTest INTERFACE locally it will try get
 * it from the remote system... THIS IS BAD. 
 * If it does load the interface remotely, the code will crash and behave badly.
 * You will get weird ClassCastException messages on perfectly good code.
 * The reason for this is that Object comes from the local system and the interface
 * depends on it, and if they come from different systems, they dont see each other.
 * So REMEMBER... the INTERFACES you cast to MUST be on the LOCAL system.
 * Its actually not a big problem because when you develop in your IDE, for example
 * look at the code above, you need to have the Interface in the local class path of
 * your application, anyway.
 * However if for example you have your interfaces in another client side library
 * and you forget to include that with your client side application, then you will
 * get this strange error.
 * While you developing you can use the vessel.verboseVessel(true) utility, and if you
 * see the interfaces coming from the server... put it in the client.
 *
 * In normal programming people tend to name the interface MyThing, and the class
 * MyThingImpl, and classes without interfaces MyThing... in all the examples we
 * name them I_Mything... so there is never any doubt which is interface and which is
 * class... they must not come from the server, here is an example of the test output
 * with the above code running....
 *
 * You should see this is your debug screen (System.out)
    Class found on local system harbor.interfaces.I_MsgTest
    Class found on local system java.lang.Object
    Class loaded from remote system harbor.classContainer.MsgTest
    Class loaded from remote system harbor.classContainer.Msg
 *
 * Very easy to forget that code is actually sitting at head office 2000 km
 * away.
 *
 * When you write your code in your dev environment...
 * This
   I_MsgTest i_MsgTest = (I_MsgTest)vessel.newInst(msgTest);
 * becomes
   I_MsgTest i_MsgTest = (I_MsgTest) new MsgTest;
 *
 * The code on the server is EXACTLY the same as it would be if it was just a
 * library used by a NORMAL POJO (Plain Old Java) application.
 *
 * EXACTLY the same... harbor is a pojo container, the idea is you
 * write normal code and then if you feel like it, drop your library modules
 * into the container and run them from the other side of the world.
 * Thats why you dont develop in the container... running code remotely can be an
 * after-thought... or conversely taking the code out of the container and testing
 * it stand-alone.... is just as easy.
 */