3 Replies Latest reply: Jan 7, 2014 8:27 AM by Martin Stam RSS

    Java Class Settings for new type

    Steve Powell Community Member
      Hi

      I've modified the example SocketGateway to create a SilentSocketGateway.

      I copied the original SocketGateway.java file and renamed it SilentSocketGateway.java. And modified the new file.

      All I have done is commented out the two lines that say hello when you first connect and modified the main function names to be SIlentSocketGateway instead of SocketGateway. So not exactly rocket science in the JAVA programming stakes.

      I haven't changed the package at the top of the java file.

      I've compiled it (javac SilentSocketGateway.class) and run the class file into a JAR file (jar -cf SilentSocketGateway.jar SilentSocketGateway.class). I've copied the resulting JAR file to the C:\CFusionMX7\gateway\lib directory.

      Restarted CF (on Windows obviously) and it finds the JAR because I can't delete it as its "in use"

      But I can't install the new type, no matter what I type in the Java Class section of the new type I get a message saying

      "Unable to find or load Gateway class examples.socket.SilentSocketGateway"

      I've tried every variation of examples.socket.SilentSocketGateway I can think of. I've moved the java file, modified the package setting, all to no avail.

      Can anyone help?

      What should I be putting in the Java Class field of the new type?

      Many thanks


      Steve
        • 1. Re: Java Class Settings for new type
          Steve Powell Community Member
          Answering my own post, how sad is that?

          Anyway after a fairly short night and several hours banging my head against this one.

          Compiling gateway classes for idiots (on windows)

          So this is not straight forward if, like me, you are a Java novice and the Coldfusion docs aren't actually that helpful.

          So here goes….

          I had a problem with the SocketGateway, the app sending us messages objected to the "Welcome to the ColdFusion Socket Gateway Connected to Socket XXXXXXX" message that you get when you initially connect to the socket.

          So I looked at the C:\CFusionMX7\gateway\src\examples\socket\SocketGateway.java file and found 2 lines of code that looked like prime suspects.


          out.println("Welcome to the ColdFusion Socket Gateway" + "\r\nConnected to Socket " + this.getName());
          out.print("> ");



          So I figured I could comment those out like this.


          // removed to prevent initial hello
          //
          // out.println("Welcome to the ColdFusion Socket Gateway" + "\r\nConnected to Socket " + this.getName());
          // out.print("> ");


          I decided not to change the actual SocketGateway.java file. I created a new directory called silentsocket alongside the socket directory and copied the java file over. I renamed it SilentSocketGateway.java so I wouldn't corrupt the original. So its final path ended up like this

          C:\CFusionMX7\gateway\src\examples\silentsocket\SilentSocketGateway.java.

          At this point I am feeling really smug, but there's a lot more pain to come.

          For one thing you have to have a Java compiler installed not just a runtime.

          Given some past experiences and the advice found on http://www.rickroot.com/blog/1/2006/02/Compiling-Custom-Event-Gateways-For-Dummies.cfm (a very good but unfortunately Unix oriented posting) I downloaded the oldest version of the Java SDK I could find. Version 1.4.2.12.


          Installing this is pretty straight forward. It installs into a directory called C:\j2sdk1.4.2_12

          Now I cheated and altered the PATH environment variable so I could access the javac compiler form anywhere. The PATH environment variable is a list of directories that Windows searches when you type something on the command line. It will look in the current directory first and then all the directories that are in the PATH environment variable until it finds something that matches what you typed and it will then run that program (or batch file if that's what it is)

          So I did this by starting a command line window Start Menu -> Run type CMD and press return.

          You will probably get booted to your default user directory F: in my case.

          So I changed to C by typing


          C:


          I then typed


          SET PATH=%PATH%;C:\j2sdk1.4.2_12\bin


          Which basically appends the Java SDK bin directory to the end of the PATH environment variable. Note there are no spaces other than the one between SET and PATH

          so now if I type


          javac


          I get some thing back explaining the syntax as javac on its own doesn't do much.

          Now unfortunately when you compile java files, if they use other java files you have to provide a classpath that javac can search to find anything it might need. Like the PATH environment varibale CLASSPATH is an enviroment variable. I set mine up like this based on the posting on Rick Roots blog.


          SET CLASSPATH=C:\CFusionMX7\lib\cfusion.jar;C:\CFusionMX7\lib\log4j.jar;C:\CFusionMX7\runtime \lib\jrun.jar;C:\CFusionMX7\gateway\lib\examples.jar;C:\j2sdk1.4.2_12\lib\tools.jar



          Now this looks odd compared to most path based environment variables because it has files in it. JAR files are basically like ZIP archives, they contain lots of other files inside them. By adding the JAR files like this you get all the things that have been compiled and zipped up. I know the Java bods amongst you are screaming that its not zipping but its an analogy I understand and probably as much as I need to know.

          So I have my PATH set and my CLASSPATH set and away we go. Well not quite so fast.

          There's a problem that we will hit later. I'm going to skip round all the things that don't work and explain what does work and what you need to watch out for.

          When you register your new gateway type in the Coldfusion administrator. You have to fill in several fields.

          The problem lies in the Java Class field. I spent several hours copying files into directories, restarting the Coldfusion service and then trying to get it to pick up my new socket. And all I got was an error message saying


          Unable to find or load Gateway class <whatever class you think you are using>


          Now having Read Rick Roots blog posting I realised I had to change a few other bits of my SilentSocketGateway.java file

          First Off right at the top I had to change the package to

          package examples.silentsocket;

          I then had to find the class declaration and constructor functions and change those to be a new class name. Basically changing SocketGateway to SilentSocketGateway.

          so


          /**
          * Socket gateway.
          * <p/>
          * This gateway listens on a socket and passes the strings read to the target CFC.
          *
          * @author Jim Schley
          */
          public class SocketGateway implements Gateway


          became


          /**
          * Socket gateway.
          * <p/>
          * This gateway listens on a socket and passes the strings read to the target CFC.
          *
          * @author Jim Schley
          */
          public class SilentSocketGateway implements Gateway


          and

          /**
          * constructor with config file
          */
          public SocketGateway(String id, String configpath)


          became


          /**
          * constructor with config file
          */
          public SilentSocketGateway(String id, String configpath)


          Now Coldfusion doesn't want a java file it doesn't even want a compiled class file. It wants a JAR file which as I mentioned is like a zip of a set of files.

          The problem that you tend to get is that the JAR needs to now about the package path prefix and have the packaged files inside it stored with the right names.

          Now I don't understand java packages in any meaningful way but I did get the always remember package = path message from several bits of docs on the web.

          I also got the whole java files to class files to jar files thing into a real mess a couple of times. So to make my life easy I created a classes folder right next to examples folder in C:\CFusionMX7\gateway\src directory

          I then compiled my java files to class files like this


          Javac -d classes examples\silentsocket\SilentSocketGateway.java


          I ran this command while in the C:\CfusionMX7\gateways\src directory as that means the path I am compiling is the same as the package identifier I altered in the SilentSocketGateway.java file.

          So at my command line I typed


          CD C:
          CD CfusionMX7
          CD gateway
          CD src


          to make sure I was in the right directory when I ran the javac command.


          This creates a set of folders in the C:\CfusionMX7\gateway\src\classes directory that reflect the package structure.



          I ended up with the files shown, quite where the other 3 turned up from I don't know. I am guessing they are supporting classes.

          So now to compile the JAR file.

          In order for the jar file to know about the package path you need to compile it form the right place. To be safe I included my own manifest file. Well I tried it about 15 times without one and it didn't work so I eventually resrted to using a manifest file

          I created a file called manifest.txt in the C:\CfusionMX7\gateway\src\classes directory

          It's content was this


          Main-Class: examples/silentsocket/SilentSocketGateway


          Its very important to make sure you have a return after the Main-Class line otherwise it doesn't work.

          I changed into the classes directory using


          CD classes


          And then built the jar file with this command


          jar -cfvm SilentSocketGateway.jar manifest.txt examples/silentsocket/*.class


          Notice that the path to the class files is once again the same as the package path, that's why we are doing this form the C:\CfusionMX7\gateway\src\classes directory

          You should get some feedback about what it is adding, the V switch stands for verbose.

          And that will give you a SilentSocketGateway.jar file in the C:\CfusionMX7\gateway\src\classes directory.

          Stop Coldfusion by stopping the Coldfusion MX 7 Application Server service.

          Copy the SilentSocketGateway.jar file to the C:\CfusionMX7\gateway\lib directory.

          Restart Coldfusion by starting the Coldfusion MX 7 Application Server service.

          You have to start and stop the service as it only picks up the jar files in the C:\CfusionMX7\gateway\lib directory when the server starts up.

          Now you can login to the Coldfusion Admin and add your gateway type


          I set my Java Class to be examples.silentsocket.SilentSocketGateway made up of the package element form the SilentSocketGateway.java file and the name of the actual class.

          This seems to work.

          Missing out the manifest file, compiling either the JAR file or the class files from any directory where the path to either the SilentSocketGateway.java or SilentSocketGateway.class files is not examples/silentsocket delivers a working class or jar file, but Coldfusion will refuse the Java Class when you try and add the new type with the message.


          Unable to find or load Gateway class <whatever class you think you are using>


          Lot of credit to Rick Root who did all the hard legwork on this long before I stuck my nose in.


          • 2. Re: Java Class Settings for new type
            RelentlessMike Community Member
            Thank you for the very informative read. And for your "Socket Gateway modifications" thread as well.

            Mike
            • 3. Re: Java Class Settings for new type
              Martin Stam Community Member

              Hmmz...

               

              So I must be missing something really stupid... (Mind you, I'm reasonably well aquainted with java but not with CF..)

               

              I'm using NetBeans to build my project and this seems to work. (No errors and I end up with a jar file.

              Although I'm building a library and not an application I díd edit my manifest file (although it didn't make much sense..) and added the 'main class'.

               

              But I still get the same error...

               

               

              Is there any way (from administration interface or a short cfm script) to tell what path and files are loaded and available? I'm starting to think I'm  barking up the wrong tree here....

               

               

              Thanks in advance.