Hi all,

I sent out the email below a little while ago, and I eventually got the
solution to clone the fact when I create the object to be serialized.  So,
in the code below, in ExData.java, I changed the fact assignment to be
assigned a clone of the fact that is a parameter of the constructor.  I
tried this and it worked just fine.  However, I now have a problem where, in
my real code, the number of facts is much greater than normal.  From not
using serialization to using serialization, I've not made any changes except
those pertaining to serialization, so the problem must have to do with
serialization and JESS.  In any case, here is the problem:   In my original
code (which didn't use serialization, the server and client were one), I
would periodically print out the number of times I had asserted a string
into the JESS engine and I would also print out the number of total facts in
the engine (the only way I could figure to do it was to get the Iterator for
the list of facts and then count up the number of items in the iteration in
a loop).  In this original code, the number of facts in the engine was
roughly 4 times the number of times I asserted a string.  This was because
each time I asserted a fact, within that fact were other "sub-facts" that
were also asserted.  The analogous variable in my example below is
list-of-IDs.  So I had a list of "sub-facts" that were asserted which were
then used to link the "top-level" facts together.

Now, when I added in the serialization and the cloning, the number of facts
in the engine jumped to 8 to 10 times the number of assertions.  Can you
think of any reason why this would happen?  Does the cloning of a fact or
serialization of a fact somehow affect the Rete itself?  The bottom line is,
I have a HUGE amount of data being processed and I am having an
OutOfMemoryError because I have too many facts in the engine.  I
periodically retract top-level facts and sub-facts, but the ratio of 8 to 10
still remains.  Any help would be highly appreciated.  Thanks!

- Nik.



-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Behalf Of Nik Joshi
Sent: Friday, January 09, 2004 7:59 PM
To: [EMAIL PROTECTED]
Subject: JESS: java/jess serialization question


Hi all,

I posted this question a while ago without any code, and I got some replies
which I tried, but to no avail.  So I've coded a simplified version of my
problem to demonstrate.  I don't know if I can send attachments to this
list, so I guess I'll have to put the code inline.  Basically, I have a java
server and client where the server has a Rete object running a JESS batch
file.   The JESS code periodically calls Userfunctions which, in turn,
serialize the Fact data and send it to the client.   The problem is that the
data in the facts does not get sent over properly.   When I de-serialize the
data on the client end, some of the slot data in the facts is missing.   In
order to run my code (see below), you need four files:  ExServer.java,
ExClient.java, ExData.java, and Exbatch.txt.   The server is run with this
usage:  java ExServer <port-number> <batch-file>  and the client is run with
this usage:  java ExClient <server-host> <server-port>.   After the client
connects to the server, the server will prompt the user to press return.
Every time the user presses return, a new fact will be asserted into the
Rete.   The facts are hardcoded into the server.


Here is the output on the server side:

>java ExServer 9988 Exbatch.txt
Server is up...
press return for first command...

Executing command: (assert (alert (name "fact0") (ID 0) (list-of-IDs)
(list-of-links cat rat dog)))
Globbed new: fact0:0 and fact0:0
a2 is: (MAIN::alert (name "fact0") (ID 0) (list-of-IDs 0) (list-of-links cat
rat dog))

about to send new cluster data...
press return for next command...

Executing command: (assert (alert (name "fact1") (ID 1) (list-of-IDs)
(list-of-links penguin horse)))
Globbed new: fact1:1 and fact1:1
a2 is: (MAIN::alert (name "fact1") (ID 1) (list-of-IDs 1) (list-of-links
penguin horse))

about to send new cluster data...
press return for next command...

Executing command: (assert (alert (name "fact2") (ID 2) (list-of-IDs)
(list-of-links sloth fish)))
Globbed new: fact2:2 and fact2:2
a2 is: (MAIN::alert (name "fact2") (ID 2) (list-of-IDs 2) (list-of-links
sloth fish))

about to send new cluster data...
press return for next command...

Executing command: (assert (alert (name "fact3") (ID 3) (list-of-IDs)
(list-of-links rat horse sloth)))
Globbed exists: fact2:2 and fact3:3
a2 is: (MAIN::alert (name "fact3") (ID 3) (list-of-IDs 2) (list-of-links rat
horse sloth))

Globbed exists: fact3:3 and fact3:3
a2 is: (MAIN::alert (name "fact3") (ID 3) (list-of-IDs 3 2) (list-of-links
rat horse sloth))

Globbed exists: fact3:3 and fact2:2
a2 is: (MAIN::alert (name "fact2") (ID 2) (list-of-IDs 3 2) (list-of-links
sloth fish))

Globbed exists: fact1:1 and fact3:3
a2 is: (MAIN::alert (name "fact3") (ID 3) (list-of-IDs 1 3 2) (list-of-links
rat horse sloth))

Globbed exists: fact3:3 and fact1:1
a2 is: (MAIN::alert (name "fact1") (ID 1) (list-of-IDs 3 1) (list-of-links
penguin horse))

Globbed exists: fact0:0 and fact3:3
a2 is: (MAIN::alert (name "fact3") (ID 3) (list-of-IDs 0 1 3 2)
(list-of-links rat horse sloth))

Globbed exists: fact3:3 and fact0:0
a2 is: (MAIN::alert (name "fact0") (ID 0) (list-of-IDs 3 0) (list-of-links
cat rat dog))




Here is the output on the client side:

>java ExClient localhost 9988
Establishing connection. Please wait ...
Connected: Socket[addr=localhost/127.0.0.1,port=9988,localport=2126]
waiting for objects...
got object...
Type: NEW
f1: (MAIN::alert (name "fact0") (ID 0) (list-of-IDs 0) (list-of-links cat
rat dog))
f2: (MAIN::alert (name "fact0") (ID 0) (list-of-IDs 0) (list-of-links cat
rat dog))


got object...
Type: NEW
f1: (MAIN::alert (name "fact1") (ID 1) (list-of-IDs 1) (list-of-links
penguin horse))
f2: (MAIN::alert (name "fact1") (ID 1) (list-of-IDs 1) (list-of-links
penguin horse))


got object...
Type: NEW
f1: (MAIN::alert (name "fact2") (ID 2) (list-of-IDs 2) (list-of-links sloth
fish))
f2: (MAIN::alert (name "fact2") (ID 2) (list-of-IDs 2) (list-of-links sloth
fish))


got object...
Type: MODIFY
f1: (MAIN::alert (name "fact3") (ID 3) (list-of-IDs 2) (list-of-links rat
horse sloth))

got object...
Type: MODIFY
f1: (MAIN::alert (name "fact3") (ID 3) (list-of-IDs 2) (list-of-links rat
horse sloth))

got object...
Type: MODIFY
f1: (MAIN::alert (name "fact2") (ID 2) (list-of-IDs 2) (list-of-links sloth
fish))

got object...
Type: MODIFY
f1: (MAIN::alert (name "fact3") (ID 3) (list-of-IDs 2) (list-of-links rat
horse sloth))

got object...
Type: MODIFY
f1: (MAIN::alert (name "fact1") (ID 1) (list-of-IDs 1) (list-of-links
penguin horse))

got object...
Type: MODIFY
f1: (MAIN::alert (name "fact3") (ID 3) (list-of-IDs 2) (list-of-links rat
horse sloth))

got object...
Type: MODIFY
f1: (MAIN::alert (name "fact0") (ID 0) (list-of-IDs 0) (list-of-links cat
rat dog))




Notice that when the server prints out a "Globbed exists" message, it
immediately sends a "MODIFY" message to the client.   So, for example, the
second to the last "Globbed exists" corresponds to the second to last
"MODIFY" message (a2 corresponds with f1).   The problem is that the
list-of-IDs multislot has gone from being "0 1 3 2" to simply "2".   This
happens with all of the "MODIFY"'s.   Where is the extra data?  In the code,
I've used the "getIcon" routine to get the "real" fact, however, it doesn't
matter whether I use it or not, I still get the same result.   Any ideas?
As always, any help is highly appreciated.  Thanks!


- Nik.



************************************************************

ExServer.java
-------------

import java.net.*;
import java.io.*;
import java.util.*;
import java.util.regex.*;
import jess.*;
import java.text.*;




public class ExServer {
        private Socket socket = null;

        private Rete r = null;

        private String batchfile = null;

        private ObjectOutputStream clientout;





        public class ModifyCluster implements Userfunction {

                // params are: fact1
                public String getName() { return ("modify-cluster"); }

                public Value call (ValueVector vv, Context context) throws 
JessException {

                        Fact f1 = vv.get(1).factValue(context);


                        ExData exd = new ExData (ExData.MODIFY, f1, null);


                        try {
                                clientout.writeObject (exd);
                        } catch (IOException ioe) {System.out.println ("got ioe: " + 
ioe);}


                        return (new Value (true));
                }
        }



        public class NewCluster implements Userfunction {

                // params are: fact1, fact2
                public String getName() { return ("new-cluster"); }

                public Value call (ValueVector vv, Context context) throws 
JessException {

                        Fact f1 = vv.get(1).factValue(context);
                        Fact f2 = vv.get(2).factValue(context);

                        ExData exd = new ExData (ExData.NEW, f1, f2);

System.out.println ("about to send new cluster data...");


                        try {
                                clientout.writeObject (exd);
                        } catch (IOException ioe) {System.out.println ("got ioe: " + 
ioe);}


                        return (new Value (true));
                }
        }






        public ExServer (int serverPort, String batchname) throws IOException {

                Socket clientsocket;
                batchfile = batchname;
                start();


                ServerSocket ss = new ServerSocket (serverPort);

                System.out.println ("Server is up...");

                clientsocket = ss.accept();

                clientout = new ObjectOutputStream (new BufferedOutputStream
(clientsocket.getOutputStream()));






                String line = "";
                String factstring = null;


                BufferedReader in = new BufferedReader (new InputStreamReader
(System.in));



                int index = 0;
                String factstrings[] = new String[4];
                factstrings[0] = "(assert (alert (name \"fact0\") (ID 0) (list-of-IDs)
(list-of-links cat rat dog)))";
                factstrings[1] = "(assert (alert (name \"fact1\") (ID 1) (list-of-IDs)
(list-of-links penguin horse)))";
                factstrings[2] = "(assert (alert (name \"fact2\") (ID 2) (list-of-IDs)
(list-of-links sloth fish)))";

                factstrings[3] = "(assert (alert (name \"fact3\") (ID 3) (list-of-IDs)
(list-of-links rat horse sloth)))";



                System.out.println ("press return for first command...");

                try {
                        while (in.readLine() != null) {

                                System.out.println ("Executing command: " + 
factstrings[index]);


                                r.executeCommand (factstrings[index]);
                                r.run();

                                index++;


                                clientout.flush();


                                System.out.println ("press return for next 
command...");
                        }
                }
                catch (JessException je) {System.out.println ("got jess exception:
"+je.getMessage()+" on line "+je.getLineNumber());
                                          System.out.println ("program text: 
"+je.getProgramText());
                                          System.out.println ("extra data: 
"+je.getData());
                                          System.out.println ("in routine: 
"+je.getRoutine());
                                          System.out.println ("context: 
"+je.getContext());
                                          System.out.println ("cause: 
"+je.getCause().toString()+"\n");}

                catch (SocketException se) {System.out.println (se.toString());
System.exit(1);}
        } /* end ExServer constructor */






        public void start() throws IOException {

                r = new Rete();
                r.addUserfunction (new NewCluster());
                r.addUserfunction (new ModifyCluster());


                try {
                        r.executeCommand ("(batch " + batchfile + ")");
                } catch (JessException je) {
                        System.out.println ("jess error: "+je.getMessage()+" on line
"+je.getLineNumber()+"\n");
                        System.out.println ("Program text: "+je.getProgramText()+"\n");
                        System.exit(1);
                }
        }


        public void stop() {
                try {
                        if (socket != null) {socket.close();}
                } catch(IOException ioe) {System.out.println("Error closing ...");}
        }


        public static void main (String args[]) throws IOException {
                ExServer client = null;

                if (args.length != 2)
                        System.out.println ("Usage: java ExServer port batchfile");
                else
                        client = new ExServer (Integer.parseInt(args[0]), args[1]);
        }
}


***********************************************************************


ExClient.java
-------------

import java.net.*;
import java.io.*;
import java.util.*;
import java.util.regex.*;
import jess.*;



public class ExClient {

        public ExClient (String serverName, int serverPort) throws IOException {


                Socket socket = null;
                ObjectInputStream in = null;

                System.out.println ("Establishing connection. Please wait ...");
                try {
                        socket = new Socket (serverName, serverPort);
                        System.out.println ("Connected: " + socket);
                }
                catch(UnknownHostException uhe) {System.out.println("Host unknown: " +
uhe.getMessage()); System.exit(1);}
                catch(IOException ioe) {System.out.println("Unexpected exception: " +
ioe.getMessage()); System.exit(1);}


                        in = new ObjectInputStream (new BufferedInputStream
(socket.getInputStream()));



System.out.println ("waiting for objects...");


                ExData theobj;

                try {

                        while ((theobj = (ExData) in.readObject()) != null) {

System.out.println ("got object...");

                                theobj.print();
System.out.println();

                        }

                } catch (SocketException se) {System.out.println (se.toString());
System.exit(1);}
                  catch (ClassNotFoundException cnfe) {System.err.println ("class not
found");}

        } /* end ExClient constructor */





        public static void main (String args[]) throws IOException {
                ExClient client = null;

                if (args.length != 2)
                        System.out.println ("Usage: java ExClient host port");
                else
                        client = new ExClient (args[0], Integer.parseInt(args[1]));
        }
}



***********************************************************


ExData.java
-----------

import java.io.*;
import jess.*;
import java.util.Vector;

public class ExData extends Object implements Serializable {

        public static final int NEW = 0;
        public static final int MODIFY = 1;
        public static final int DELETE = 2;
        public static final int END = 3;


        public int type;
        public Fact f1;
        public Fact f2;


        public ExData (int type, Fact f1, Fact f2) {
                this.type = type;
                this.f1 = f1;
                this.f2 = f2;
        }


        public void print() {
                if (type==NEW) {System.out.println ("Type: NEW");}
                else if (type==MODIFY) {System.out.println ("Type: MODIFY");}
                else if (type==DELETE) {System.out.println ("Type: DELETE");}
                else if (type==END) {System.out.println ("Type: END");}

                if (f1 != null) {System.out.println ("f1: " + f1.toString());}
                if (f2 != null) {System.out.println ("f2: " + f2.toString() + "\n");}
        }
}



********************************************************



Exbatch.txt
-----------

(clear)
(reset)


(deftemplate alert
        (slot name (type STRING))
        (slot ID)
        (multislot list-of-IDs)
        (multislot list-of-links)
)





; if cluster exists
(defrule alertglob2

        (declare (salience 200))

        ?a2 <- (alert (name ?name2) (ID ?id2) (list-of-links $? ?link2 $?)
(list-of-IDs $?list2))

        ?a1 <- (alert (name ?name1) (ID ?id1) (list-of-links $? ?link2 $?)
(list-of-IDs $?list1))


        (test (> (length$ $?list1) 0))

        (test (not (member$ ?id1 $?list2)))
=>
        (printout t "Globbed exists: " ?name1 ":" ?id1 " and " ?name2 ":" ?id2
crlf)


        (modify ?a2 (list-of-IDs (insert$ $?list2 1 ?id1)))


(printout t "a2 is: " (?a2 toString) crlf crlf)


        (modify-cluster (?a2 getIcon))
)





; if cluster does not exist
(defrule alertglob1

        (declare (salience 100))

        ?a2 <- (alert (name ?name2) (ID ?id2) (list-of-links $? ?link2 $?)
(list-of-IDs $?list2))

        ?a1 <- (alert (name ?name1) (ID ?id1) (list-of-links $? ?link2 $?)
(list-of-IDs $?list1))


        (test (not (member$ ?id1 $?list2)))
=>
        (printout t "Globbed new: " ?name1 ":" ?id1 " and " ?name2 ":" ?id2 crlf)


        (modify ?a2 (list-of-IDs (insert$ $?list2 1 ?id1)))

(printout t "a2 is: " (?a2 toString) crlf crlf)


        (new-cluster (?a1 getIcon) (?a2 getIcon))



;(printout t "finished alertglob1" crlf)
; (facts)

)

--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------

--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------

Reply via email to