Question

I am coding a small Jess application via a Apache Tomcat server. I am utalising servlets to take input from a user and output Jess results. I have my files in a folder under webapps in the Tomcat directory. I am getting no exceptions or errors logged but the the final stage of the application to return a list of results from jess.jar is not working.

Questions for a user are sucessfully loaded on a jsp via 'java.util.Iterator', from a jess .clp file. A class file is coded to carry out the next two steps of putting the answers into jess slots, and then returning resulting created facts from rules. I think the second step of putting the answers from questions into slots is working, but the final step of displaying created facts is not working.

I will paste the java code in question below if some assistance can be offered please:

import jess.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.Iterator;

public class Results extends BaseServlet {

public void doGet(HttpServletRequest request,
                   HttpServletResponse response)
    throws IOException, ServletException {
    checkInitialized();

    ServletContext servletContext = getServletContext();
    Iterator iter = (Iterator)request.getSession().getAttribute("queryResult1"); 
    String[] answers = (String[]) request.getParameterValues("answers");
    String sessionNumberString =
        (String) request.getSession().getAttribute("sessionNumber");
    String userNameString =
        (String) request.getSession().getAttribute("username");
    if (answers == null ||
        sessionNumberString == null || userNameString == null) {
        dispatch(request, response, "/index.html");
        return;
    }

    try {
        Rete engine = (Rete) servletContext.getAttribute("engine");

        engine.run();

        int sessionNumber = Integer.parseInt(sessionNumberString);
        Value sessionNumberValue = new Value(sessionNumber, RU.INTEGER);
        Value userNameValue = new Value(userNameString, RU.ATOM);
        Fact session = new Fact("session", engine);
        session.setSlotValue("session-number", sessionNumberValue);
        session.setSlotValue("user-name", userNameValue);
        engine.assertFact(session);


         while (iter.hasNext()) {
                Token token = (Token) iter.next();
                Fact fact = token.fact(1);
                String identity =
                    fact.getSlotValue("ident").stringValue(null);

                for (int i=0; i<answers.length; ++i) {
                Fact answer = new Fact("answer", engine);
                answer.setSlotValue("ident", new Value(identity, RU.ATOM));
                answer.setSlotValue("text", new Value(answers[i], RU.ATOM));
                engine.assertFact(answer);
            }
        }

        engine.run();
        Iterator result =
            engine.runQuery("all-analysis", new ValueVector());

        if (result.hasNext()) {
            request.setAttribute("queryResult2", result);
            dispatch(request, response, "/results.jsp");
        } else
            dispatch(request, response, "/error-results.html");

    } catch (JessException je) {
        throw new ServletException(je);
    }

}
}

Iterator iter is a query result from jess appended from the previous servlet which displays the question result fine. In the above code iter.hasNext() appears to work around line 41 and passes the slot value of ident with no errors. I want the slot value of 'ident' and 'text' to create answer deftemplate facts in the order the questions have been answered. This step produces no apparent errors.

Final step is to collect resulting facts created, from asserted answer facts, but there are no analysis facts it seems to collect? The if-else statement at line 43 gets executed and displays 'error-results.html' instead of what I want 'results.jsp'. What is my error? Basically I think Iterator result has no next for some reason.

I will paste my Jess .clp file is someone needs to see it.

Help is appreciated, thank you.

Was it helpful?

Solution

First of all, query results are pointers to internal data structures, and as such they are transient things. You're intended to consume them immediately. In the code above I see you calling Rete.run() and asserting a number of facts before iterating through a previously-executed query's results. Don't do that! After running a query, you should immediately extract the results you need into a collection of some kind (a List or Map) and then pass that collection around as needed.

Secondly, we would need to see the *.clp file to diagnose this, but I don't think we should -- I'd rather help you to do that yourself. One of four things must be going wrong here:

  1. The way you're using the query result is breaking things;
  2. The facts you think are being asserted here aren't correct;
  3. The rules aren't producing the results you expect;
  4. The query all-analysis doesn't return the results you expect.

What you need to do is disprove each of these in turn until you find the problem. First, modify the program so that query results are only used immediately after use, and definitely don't assert facts as you iterate through them!

Second, use a Jess facility (like the save-facts function) to dump the contents of working memory after you assert the new facts here and check them.

Third, use save-facts again after the run(), again, to check that the answers you're looking for actually exist.

Finally, if your final query still doesn't give the right results, then it must be incorrect, so have a closer look at it!

Good luck tracking down your problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top