Information about drools runtime - java
I need to access run-time information of running drools engine in my java web-app.
Things i need to know:
what are the active rules in run-time at any instant?
How much objects are inserted into session till now?
Are there some classes that let you access the information of drools run-time?
Thanks in advance
You just need to examine the KnowledgeBase and StatefulKnowledgeSession classes. The following methods demonstrate how to get hold of all rules in your knowledge base, and all facts in working memory.
/**
* Get a String showing all packages and rules in a knowledge base.
*/
public String kbString(KnowledgeBase kbase) {
StringBuilder sb = new StringBuilder();
for (KnowledgePackage p : kbase.getKnowledgePackages()) {
sb.append("\n Package : " + p.getName());
for (Rule r : p.getRules()) {
sb.append("\n Rule: " + r.getName());
}
}
return "Knowledge base built with packages: " + sb.toString();
}
/**
* Get a String showing the facts currently in working memory,
* and their details.
*
* #param session The session to search for facts.
*/
public String sessionFactsString(StatefulKnowledgeSession session) {
StringBuilder sb = new StringBuilder();
sb.append("\nThe following facts are currently in the system...");
for (Object fact : session.getObjects()) {
sb.append("\n\nFact: " + DroolsUtil.objectDetails(fact));
}
return sb.toString();
}
Edit for clarity - The objectDetails(Object) method above is a method for rendering any old Java bean as a String, using Apache Commons BeanUtils. It looks like this:
public static String objectDetails(Object o) {
StringBuilder sb = new StringBuilder(o.getClass().getSimpleName());
try {
#SuppressWarnings("unchecked")
Map<String, Object> objectProperties = BeanUtils.describe(o);
for (String k : objectProperties.keySet()) {
sb.append(", " + k + "=\"" + objectProperties.get(k) + "\"");
}
} catch (IllegalAccessException e) {
return "IllegalAccessException attempting to parse object.";
} catch (InvocationTargetException e) {
return "InvocationTargetException attempting to parse object.";
} catch (NoSuchMethodException e) {
return "NoSuchMethodException attempting to parse object.";
}
return sb.toString();
}
For debug purposes you can also add these listeners to the KnowledgeSession
Drools has an event model that exposes much of whats happening
internally, two default debug listeners are supplied
DebugAgendaEventListener and DebugWorkingMemoryEventListener which
print out debug event information to the err console, adding listeners
to a session is trivial and shown below. The WorkingMemoryFileLogger
provides execution auditing which can be viewed in a graphical viewer;
it's actually a specialised implementation built on the agenda and
working memory listeners, when the engine has finished executing
logger.writeToDisk() must be called.
ksession.addEventListener(new DebugAgendaEventListener()); // add 2 debug event listeners
ksession.addEventListener(new DebugWorkingMemoryEventListener());
// setup the audit logging
WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger( session );
logger.setFileName( "log/helloworld" );
Related
Azure Document DB - Java 1.9.5 | Authorization Error
I have a collection with some documents in it. And in my application I am creating this collection first and then inserting documents. Also, based on the requirement I need to truncate (delete all documents) the collection as well. Using document db java api I have written the following code for my this purpose- DocumentClient documentClient = getConnection(masterkey, server, portNo); List<Database> databaseList = documentClient.queryDatabases("SELECT * FROM root r WHERE r.id='" + schemaName + "'", null).getQueryIterable().toList(); DocumentCollection collection = null; Database databaseCache = (Database)databaseList.get(0); List<DocumentCollection> collectionList = documentClient.queryCollections(databaseCache.getSelfLink(), "SELECT * FROM root r WHERE r.id='" + collectionName + "'", null).getQueryIterable().toList(); // truncate logic if (collectionList.size() > 0) { collection = ((DocumentCollection) collectionList.get(0)); if (truncate) { try { documentClient.deleteDocument(collection.getSelfLink(), null); } catch (DocumentClientException e) { e.printStackTrace(); } } } else { // create logic RequestOptions requestOptions = new RequestOptions(); requestOptions.setOfferType("S1"); collection = new DocumentCollection(); collection.setId(collectionName); try { collection = documentClient.createCollection(databaseCache.getSelfLink(), collection, requestOptions).getResource(); } catch (DocumentClientException e) { e.printStackTrace(); } With the above code I am able to create a new collection successfully. Also, I am able to insert documents as well in this collection. But while truncating the collection I am getting below error- com.microsoft.azure.documentdb.DocumentClientException: The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign: 'delete colls eyckqjnw0ae= I am using Azure Document DB Java API version 1.9.5. It will be of great help if you can point out the error in my code or if there is any other better way of truncating collection. I would really appreciate any kind of help here.
According to your description & code, I think the issue was caused by the code below. try { documentClient.deleteDocument(collection.getSelfLink(), null); } catch (DocumentClientException e) { e.printStackTrace(); } It seems that you want to delete a document via the code above, but pass the argument documentLink with a collection link. So if your real intention is to delete a collection, please using the method DocumentClient.deleteCollection(collectionLink, options).
Can't resolve Log Forging Fortify issue
I am having trouble fixing a Log Forging issue in Fortify. The issue, "writes unvalidated user input to the log", is being raised from both of the logging calls in the getLongFromTimestamp() method. public long getLongFromTimestamp(final String value) { LOGGER.info("getLongFromTimestamp(" + cleanLogString(value) + ")"); long longVal = 0; Date tempDate = null; try { tempDate = new SimpleDateFormat(FORMAT_YYYYMMDDHHMMSS, Locale.US).parse(value); } catch (ParseException e) { LOGGER.warn("Failed to convert to Date: " + cleanLogString(value) + " Exception: " + cleanLogString(e.getMessage())); throw new Exception(e); } if (tempDate != null) { longVal = tempDate.getTime(); } return longVal; } private cleanLogString(String logString) { String clean = logString.replaceAll("[^A-Za-z0-9]", ""); if(!logString.equals(clean)) { clean += " (CLEANED)"; } return clean; } The cleanLogString() method has fixed other Log Forging Fortify issues in my project, however it has no effect on the 2 above. Any help would be appreciated!
It is possible to use fortify Java annotations to tell Fortify that the data returned from a sanitizing function is now safe. When looking at my log forging problems I had strings coming in through a web API and thus had the flags XSS and WEB on my strings. I tried to find annotations that would only remove these flags, but couldn't find any way to remove the WEB flag. The only documentation I've found is the Samples/advanced/javaAnnotation directory. Since my sanitation method does sanitize strings, I choose to remove all flags. This could be a problem though, as it could hide privacy violations. #FortifyValidate("return") private String sanitizeString(String taintedString) { return doSomethingWithTheString(taintedString); }
Originally when this question was written our team was using log4j v1.2.8, however we noticed that all the log forging issues disappeared after upgrading to log4j v2.6.2. Once the log4j version is upgraded the Fortify log forging issues should go away. The cleanLogString() method form the question above is also unnecessary. For example: LOGGER.info("getLongFromTimestamp(" + value + ")");
I know I have run into situations where the complexity of my application would stop any malicious input from working as intended; Fortify does not consider this to be secure. I bet you are running into the same thing. You are stripping any really useful characters out of the log message, but see what happens if you do some encoding on the output prior to writing to the log. http://www.jtmelton.com/2010/09/21/preventing-log-forging-in-java/ // ensure no CRLF injection into logs for forging records String clean = message.replace( '\n', '_' ).replace( '\r', '_' ); if ( ESAPI.securityConfiguration().getLogEncodingRequired() ) { clean = ESAPI.encoder().encodeForHTML(message); if (!message.equals(clean)) { clean += " (Encoded)"; } }
Use reflect or try-catch. Its easy to cheat fortify.
Using a Commonj Work Manager to send Asynchronous HTTP calls
I switched from making sequential HTTP calls to 4 REST services, to making 4 simultaneous calls using a commonj4 work manager task executor. I'm using WebLogic 12c. This new code works on my development environment, but in our test environment under load conditions, and occasionally while not under load, the results map is not populated with all of the results. The logging suggests that each work item did receive back the results though. Could this be a problem with the ConcurrentHashMap? In this example from IBM, they use their own version of Work and there's a getData() method, although it doesn't like that method really exists in their class definition. I had followed a different example that just used the Work class but didn't demonstrate how to get the data out of those threads into the main thread. Should I be using execute() instead of schedule()? The API doesn't appear to be well documented. The stuckthreadtimeout is sufficiently high. component.processInbound() actually contains the code for the HTTP call, but I the problem isn't there because I can switch back to the synchronous version of the class below and not have any issues. http://publib.boulder.ibm.com/infocenter/wsdoc400/v6r0/index.jsp?topic=/com.ibm.websphere.iseries.doc/info/ae/asyncbns/concepts/casb_workmgr.html My code: public class WorkManagerAsyncLinkedComponentRouter implements MessageDispatcher<Object, Object> { private List<Component<Object, Object>> components; protected ConcurrentHashMap<String, Object> workItemsResultsMap; protected ConcurrentHashMap<String, Exception> componentExceptionsInThreads; ... //components is populated at this point with one component for each REST call to be made. public Object route(final Object message) throws RouterException { ... try { workItemsResultsMap = new ConcurrentHashMap<String, Object>(); componentExceptionsInThreads = new ConcurrentHashMap<String, Exception>(); final String parentThreadID = Thread.currentThread().getName(); List<WorkItem> producerWorkItems = new ArrayList<WorkItem>(); for (final Component<Object, Object> component : this.components) { producerWorkItems.add(workManagerTaskExecutor.schedule(new Work() { public void run() { //ExecuteThread th = (ExecuteThread) Thread.currentThread(); //th.setName(component.getName()); LOG.info("Child thread " + Thread.currentThread().getName() +" Parent thread: " + parentThreadID + " Executing work item for: " + component.getName()); try { Object returnObj = component.processInbound(message); if (returnObj == null) LOG.info("Object returned to work item is null, not adding to producer components results map, for this producer: " + component.getName()); else { LOG.info("Added producer component thread result for: " + component.getName()); workItemsResultsMap.put(component.getName(), returnObj); } LOG.info("Finished executing work item for: " + component.getName()); } catch (Exception e) { componentExceptionsInThreads.put(component.getName(), e); } } ... })); } // end loop over producer components // Block until all items are done workManagerTaskExecutor.waitForAll(producerWorkItems, stuckThreadTimeout); LOG.info("Finished waiting for all producer component threads."); if (componentExceptionsInThreads != null && componentExceptionsInThreads.size() > 0) { ... } List<Object> resultsList = new ArrayList<Object>(workItemsResultsMap.values()); if (resultsList.size() == 0) throw new RouterException( "The producer thread results are all empty. The threads were likely not created. In testing this was observed when either 1)the system was almost out of memory (Perhaps the there is not enough memory to create a new thread for each producer, for this REST request), or 2)Timeouts were reached for all producers."); //** The problem is identified here. The results in the ConcurrentHashMap aren't the number expected . if (workItemsResultsMap.size() != this.components.size()) { StringBuilder sb = new StringBuilder(); for (String str : workItemsResultsMap.keySet()) { sb.append(str + " "); } throw new RouterException( "Did not receive results from all threads within the thread timeout period. Only retrieved:" + sb.toString()); } LOG.info("Returning " + String.valueOf(resultsList.size()) + " results."); LOG.debug("List of returned feeds: " + String.valueOf(resultsList)); return resultsList; } ... } }
I ended up cloning the DOM document used as a parameter. There must be some downstream code that has side effects on the parameter.
Strange behaviour with indexOf method
We have deployed our Java EE web application in jboss 4.0.2 (we are using JDK 1.6.0_18). In our code we are iterating through the Collection and doing string concatenation of userids in collection (refer below code). On production server, it behaves inconsistently. The userid (2044157) is not found in final string (refer ServerLog line3). If we restart the production jboss server, then it works perfectly fine and it prints all users correctly in final string log. But the problem again reappears after heavy usage (after 5-6 hours). We are not able to replicate the issue on our QA environment. When problem happens, Looks like the indexOf method incorrectly returns that 2044157 is there in strUsers string (even though 2044157 is not there) and hence it goes into else part and printed it in else part log(refer ServerLog line2 - highlighted in bold font). What could be reason for such inconsistent behavior? Code: public class UsersEJB implements SessionBean{ private void processSelectionData{ StringBuilder strUsers = new StringBuilder(""); Collection userVoCollection = dc.retProjectOrgUsers(projectID, strDistributionCompID, porjectDataSource); // This is returning List of 626 UserVO if(log.isDebugEnabled()) log.debug("UserList Size="+userVoCollection.size()+",B4 strUsers="+strUsers.toString()); Iterator it = userVoCollection.iterator(); while(it.hasNext()) { UserVO uVO = (UserVO)it.next(); if(!(strUsers.toString().indexOf("," + uVO.userID.toString() + ",") > -1)) { strUsers.append(uVO.userID.toString()).append(","); loopCntPos++; } else { loopCntNeg++; if(log.isDebugEnabled()) log.debug("UserId="+uVO.userID.toString()+",strUsers="+loopCnt+"="+strUsers.toString()); } loopCnt++; } if(log.isDebugEnabled()) log.debug("COMPANIES_ID1 strUsers="+strUsers.toString() + ",### loopCnt="+loopCnt + ",loopCntPos="+loopCntPos + ",loopCntNeg="+loopCntNeg); } } ServerLog UserList Size=626,B4 strUsers=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071, UserId=2044157,strUsers=440=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071,1893797,2137701,2025815,1522850,2027582,1732833,1984513,2037965,1900381,1731514,2044357,2042751,1785407,2118267,2050509,2062445,1934909,1912411,1733673,1731956,1694916,1731951,2048024,1735552,2115155,1732777,2120796,2048007,1845970,1738356,1841988,2101099,2027667,2067876,1734628,1731739,1731893,2051612,1819645,1803654,2037906,1732047,1478544,2073677,2012435,2067977,2073669,1981390,1731124,15916,6766,1978916,1732750,1936298,1891936,1747650,1949484,2101161,1928883,1948164,2013726,1750718,1732164,1733700,1639298,1734968,1732007,1734723,1949403,2137692,1990151,1734617,2101130,1928888,2044163,1732042,1819543,2137672,1735463,1732716,1950975,2025826,1984507,2017645,1372949,1928719,1732684,1952358,1581015,2026878,1731622,1734036,2000528,1734611,2052691,1961286,2107121,1733335,1868846,2000469,1734771,1841953,2118224,2038924,1731609,1735396,2026033,1805573,2107214,1638397,1731502,1731581,2115171,2120903,1892076,2060862,2017603,2002514,1731351,1901274,1760679,1821298,1884485,1777244,1731204,1934917,2000497,1737101,2115043,2121909,2097818,1506144,1953947,1753401,1594875,2135263,1900276,1907168,1851867,1940057,1897000,1765857,2037953,1907085,2037911,2062548,1650062,1801180,1953696,2119602,1605403,1804076,1669286,1844334,1542596,2048001,1938656,1757959,1529666,2070447,1565121,1907065,1944060,2097808,2077490,1843170,1957289,1690800,1823148,1788987,1912477,1738344,1845866,2047996,1962156,1483244,2071932,2127277,1912419,1756748,1999518,1908161,1722312,1548164,1584044,2047896,1856844,1762432,2073439,1861949,1530755,1989292,1852455,2027658,1738380,2067996,1981507,1998543,1958859,1620837,1852555,2012357,1895444,2050380,1789210,1932156,1898948,2046841,2098171,1625335,2138533,2046655,1785464,2105080,2024935,1852446,2073682,1478644,2103660,1751154,1863254,1478332,1849259,1593399,1895334,2075182,2134365,2136657, COMPANIES_ID1 strUsers=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071,1893797,2137701,2025815,1522850,2027582,1732833,1984513,2037965,1900381,1731514,2044357,2042751,1785407,2118267,2050509,2062445,1934909,1912411,1733673,1731956,1694916,1731951,2048024,1735552,2115155,1732777,2120796,2048007,1845970,1738356,1841988,2101099,2027667,2067876,1734628,1731739,1731893,2051612,1819645,1803654,2037906,1732047,1478544,2073677,2012435,2067977,2073669,1981390,1731124,15916,6766,1978916,1732750,1936298,1891936,1747650,1949484,2101161,1928883,1948164,2013726,1750718,1732164,1733700,1639298,1734968,1732007,1734723,1949403,2137692,1990151,1734617,2101130,1928888,2044163,1732042,1819543,2137672,1735463,1732716,1950975,2025826,1984507,2017645,1372949,1928719,1732684,1952358,1581015,2026878,1731622,1734036,2000528,1734611,2052691,1961286,2107121,1733335,1868846,2000469,1734771,1841953,2118224,2038924,1731609,1735396,2026033,1805573,2107214,1638397,1731502,1731581,2115171,2120903,1892076,2060862,2017603,2002514,1731351,1901274,1760679,1821298,1884485,1777244,1731204,1934917,2000497,1737101,2115043,2121909,2097818,1506144,1953947,1753401,1594875,2135263,1900276,1907168,1851867,1940057,1897000,1765857,2037953,1907085,2037911,2062548,1650062,1801180,1953696,2119602,1605403,1804076,1669286,1844334,1542596,2048001,1938656,1757959,1529666,2070447,1565121,1907065,1944060,2097808,2077490,1843170,1957289,1690800,1823148,1788987,1912477,1738344,1845866,2047996,1962156,1483244,2071932,2127277,1912419,1756748,1999518,1908161,1722312,1548164,1584044,2047896,1856844,1762432,2073439,1861949,1530755,1989292,1852455,2027658,1738380,2067996,1981507,1998543,1958859,1620837,1852555,2012357,1895444,2050380,1789210,1932156,1898948,2046841,2098171,1625335,2138533,2046655,1785464,2105080,2024935,1852446,2073682,1478644,2103660,1751154,1863254,1478332,1849259,1593399,1895334,2075182,2134365,2136657,2041203,2043944,2040358,2093521,1913544,2082455,2024959,2045812,1973980,1494485,1986446,1525605,2046849,1785194,1822210,2053401,1918823,2001794,1785258,2064339,1986338,1710198,1521244,1822292,1931276,2134370,2075073,2134300,2075068,1521210,2131493,1951008,1914649,1774999,1601557,1485584,2078975,1986330,1612190,2064410,2066054,1985760,1685075,1930273,2032161,1955161,,### loopCnt=626,loopCntPos=274,loopCntNeg=352
As it stands, your search won't pick up the first user as there won't be a preceding comma. However, I would suggest solving the problem in a far simpler manner, by using a set: public class UsersEJB implements SessionBean { private void processSelectionData { Collection userVoCollection = dc.retProjectOrgUsers(projectID, strDistributionCompID, porjectDataSource); // This is returning List of 626 UserVO Set<String> usersSet = new HashSet<String>(userVoCollection.size()); if(log.isDebugEnabled()) log.debug("UserList Size="+userVoCollection.size()+",B4 strUsers="+strUsers.toString()); for (UserVO uVO : userVoCollection) { if (usersSet.add(uVO.userID.toString()) loopCntPos++; else { loopCntNeg++; if(log.isDebugEnabled()) log.debug("UserId="+uVO.userID.toString()+",strUsers="+loopCnt+"="+strUsers.toString()); } if(log.isDebugEnabled()) log.debug("COMPANIES_ID1 strUsers=" + usersSet + ",### loopCnt="+loopCnt + ",loopCntPos="+loopCntPos + ",loopCntNeg="+loopCntNeg); } }
Android application exits without any exception
I'm building an application that shows in a WebView some remote data that is cached in SQLite db. The data is being requested by JavaScript function from WebView via JavaScript interface. When user types into an input element on the page, JavaScript function requests search result by calling Java function, which in turn fires a sql query. Results are then packaged in suitable JSON format and returned. Fetching data works OK unless you type very quickly. If you type quick enough after few key presses the app quits WITHOUT any exceptions being thrown, it just goes back to home screen. I have managed to narrow down the cause - commenting out the call to .query method prevents crashing, but renders app useless. Is there a way to check what caused application to quit, another log or tool that could help? Java function code: public Lot[] getLotList(String query, int limitCount) { ... ... String[] resultColumns = new String[] { LotsSearch._ID }; String queryWhere = LotsSearch.TABLE_NAME + " MATCH ?"; String[] queryArgs = new String[] { query + "*" }; String sortOrder = LotsSearch.COLUMN_NAME_NUMBER + " ASC, " + LotsSearch.COLUMN_NAME_TITLE + " ASC"; String limit = null; Cursor cursor = null; if (limitCount != -1) limit = "0," + limitCount; try { cursor = mDb.query(LotsSearch.TABLE_NAME, resultColumns, queryWhere, queryArgs, null, null, sortOrder, limit); if (cursor != null && cursor.moveToFirst()) { result = new Lot[cursor.getCount()]; try { int idColumnIndex = cursor.getColumnIndexOrThrow(LotsSearch._ID); int lotId; Lot lot; do { lotId = cursor.getInt(idColumnIndex); lot = mLots.get(lotId); if (lot != null) result[index++] = lot; } while (cursor.moveToNext()); } catch (IllegalArgumentException e) { e.printStackTrace(); } } } catch (SQLiteException e) { e.printStackTrace(); } finally { if (cursor != null) cursor.close(); } ... ... return result; } UPDATE: I have discovered that there is another log that could be accessed by issuing logcat -b events when the app crashes there is just one entry I/am_proc_died( 59): [11473,com.example.app] and when the app exits gracefuly this log shows set of entries: I/am_finish_activity( 59): [1157978656,22,com.example.app/.MainActivity,app-request] I/am_pause_activity( 59): [1157978656,com.example.app/.MainActivity] I/am_on_paused_called(11473): com.example.app.MainActivity I/am_destroy_activity( 59): [1157978656,22,com.example.app/.MainActivity]
I'd make a change to my auto search function. Namely, only perform the search if the user hasn't pressed a key for about 1/2 a second. If you are typing fast, then this function is being executed several times right on top of itself, before the results are even able to come back. Meanwhile you are probably have too many cursor resources going at once causing the app to just completely fail. update. If you consider it, typing 10 keys fairly quickly in a row could potentially mean that you have 10 different queries executing and parsing results... There could certainly be some deadlocking issues with the code that actually calls the getLotList method if it's spun multiple threads to try and update the UI. This can lead to some programs simply giving up the ghost not knowing what to do or even what thread to report the issue on. Of course, all of that's hard to tell from the small snippet we have.