-
1. Re: Old VFS files being read.
jaikiran Apr 3, 2014 9:29 AM (in response to richard.hart)Richard Hart wrote:
The application will work for a period of time, but I see from our log file that for some unkown reason, JBoss apparently reloads the singleton class and the initialization of the class begins by reading the drools rules files but this time through, the path in the tmp directory resolved by VFS has changed from the first time the class was initialized resulting in an old rule files being read.
Perhaps in the context of a different classloader? Remember, singletons aren't really singletons per JVM but they are per classloader.
I am at a loss as to the reason why the VFS class resolves the path to an old one
When you say VFS, are you explicitly using any VFS API within the application? If yes, which one and what does that code look like?
-
2. Re: Old VFS files being read.
richard.hart Apr 3, 2014 10:37 AM (in response to jaikiran)Here is the code used to initialize the drools knowledgebase. This class (DroolsUtil) is a singleton.
public void initializeKnowledgebase() { final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory .newKnowledgeBuilder(); List listOfFiles = new ArrayList(); try { listOfFiles = getListOfFiles(); } catch (final IOException | URISyntaxException e) { log.error("Unexpected Exception reading drools resource files.", e); } for (final File file : listOfFiles) { final String[] tokens = file.getName().split("\\.(?=[^\\.]+$)"); log.info("reading file " + file.toURI().getPath()); try (Reader reader = new FileReader(file)) { final Resource myResource = ResourceFactory .newReaderResource(reader); switch (tokens[1].toLowerCase()) { case "bpmn2": kbuilder.add(myResource, ResourceType.BPMN2); break; case "brl": kbuilder.add(myResource, ResourceType.BRL); break; case "change_set": kbuilder.add(myResource, ResourceType.CHANGE_SET); break; case "descr": kbuilder.add(myResource, ResourceType.DESCR); break; case "drf": kbuilder.add(myResource, ResourceType.DRF); break; case "drl": kbuilder.add(myResource, ResourceType.DRL); break; case "dsl": kbuilder.add(myResource, ResourceType.DSL); break; case "dslr": kbuilder.add(myResource, ResourceType.DSLR); break; case "dtable": kbuilder.add(myResource, ResourceType.DTABLE); break; case "pkg": kbuilder.add(myResource, ResourceType.PKG); break; case "pmml": kbuilder.add(myResource, ResourceType.PMML); break; case "xdrl": kbuilder.add(myResource, ResourceType.XDRL); break; case "xsd": kbuilder.add(myResource, ResourceType.XSD); break; default: log.error("Invalid file extention '" + tokens[1] + "' for Drools ResourceType. File " + file.getAbsolutePath() + " not loaded into KnowledgeBase."); break; } } catch (final IOException e) { log.warn("Unexpected IOException.", e); ; // intentionally left blank. Potentially thrown on close // of // reader. } } final KnowledgeBuilderErrors errors = kbuilder.getErrors(); if (errors.size() > 0) { final StringBuilder errorMsgBuilder = new StringBuilder( "Could not parse knowledge.\n"); for (final KnowledgeBuilderError error : errors) { log.error("KnowledgeBuilderError:\n" + error.getMessage()); errorMsgBuilder.append(error.getMessage() + "\n"); } throw new IllegalArgumentException(errorMsgBuilder.toString()); } internKnowledgeBase = KnowledgeBaseFactory.newKnowledgeBase(); internKnowledgeBase.addKnowledgePackages(kbuilder .getKnowledgePackages()); }
This is the getListOfFiles method called above. This is the method that can use VFS. VFS is used only if the files cannot be found using standard Java classes. Only on the Linux system is VFS used. This method is in the FileUtil class that is NOT a singleton, just a static method in the class.
public static List getListOfFiles(String path) throws IOException, URISyntaxException { final List listOfFiles = new ArrayList(); URI classPath = null; if (DroolsUtil.RULES_PATH.equals(path)) { classPath = FileUtil.class.getResource("/" + path).toURI(); } else { classPath = new URI(path); } log.info("classPath = " + classPath); URL url = classPath.toURL(); //Thread.currentThread().getContextClassLoader().getResource(path); final File file = new File(url.getFile()); final File[] fileArray = file.listFiles(); if (fileArray != null) { for (int i = 0; i < fileArray.length; i++) { listOfFiles.add(fileArray[i]); } } else { log.info("No files found at " + url.getFile() + " Trying with VFS."); try { final URI uri = url.toURI(); final VirtualFile vf = VFS.getChild(uri); if (vf.isDirectory()) { final List vFiles = vf.getChildren(); for (final VirtualFile tempVf : vFiles) { final File vfile = tempVf.getPhysicalFile(); listOfFiles.add(vfile); } if (listOfFiles.size() == 0) { throw new IllegalArgumentException("No files found using VFS at " + uri.getPath()); } return listOfFiles; } } catch (final URISyntaxException e) { log.error("Unexpected URISyntaxError", e); } } return listOfFiles; }
I was previously using Thread.currentThread().getContextClassLoader().getResource(path) but I changed to using the FileUtil (non-singleton) classloader. This has not fixed the issue.
In this case DroolsUtil.RULES_PATH does equal path which is "rules" which is the directory under the deployment classes directory.
I should be using VFS3. The imports are:
import org.jboss.vfs.VFS; import org.jboss.vfs.VirtualFile;
And here is an example from the log file: It starts good then some time later, initialization of the singleton happens again pointing to old rule files. No builds, no deployments, nothing other than using the application happened between the two initializations. I have no idea why JBoss needs to reload the DroolsUtil singleton.
2014-04-03/13:51:23 [com.pwc.fdb.utils.FileUtil] INFO classPath = vfs:/content/voyager.war/WEB-INF/classes/rules/ 2014-04-03/13:51:23 [com.pwc.fdb.utils.FileUtil] INFO No files found at /content/voyager.war/WEB-INF/classes/rules/ Trying with VFS. 2014-04-03/13:51:23 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-9388a94e003f8800/WEB-INF/classes/rules/CoACalcsExcludingTime.drl 2014-04-03/13:51:26 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-9388a94e003f8800/WEB-INF/classes/rules/FdbRuleFlowMaster.bpmn2 2014-04-03/13:51:28 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-9388a94e003f8800/WEB-INF/classes/rules/TestRuleFlow.drl . . . 2014-04-03/16:20:23 [com.pwc.fdb.utils.FileUtil] INFO classPath = vfs:/content/voyager.war/WEB-INF/classes/rules/ 2014-04-03/16:20:23 [com.pwc.fdb.utils.FileUtil] INFO No files found at /content/voyager.war/WEB-INF/classes/rules/ Trying with VFS. 2014-04-03/16:20:23 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-81e2935cd45e3fc1/WEB-INF/classes/rules/CoACalcsExcludingTime.drl 2014-04-03/16:20:25 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-81e2935cd45e3fc1/WEB-INF/classes/rules/FdbRuleFlowMaster.bpmn2 2014-04-03/16:20:26 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-81e2935cd45e3fc1/WEB-INF/classes/rules/README.TXT 2014-04-03/16:20:26 [com.pwc.fdb.utils.DroolsUtil] ERROR Invalid file extention 'TXT' for Drools ResourceType. File /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-81e2935cd45e3fc1/WEB-INF/classes/rules/README.TXT not loaded into KnowledgeBase. 2014-04-03/16:20:26 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-81e2935cd45e3fc1/WEB-INF/classes/rules/test.drl 2014-04-03/16:20:27 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-81e2935cd45e3fc1/WEB-INF/classes/rules/Sample.drl 2014-04-03/16:20:28 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-81e2935cd45e3fc1/WEB-INF/classes/rules/sample rules.drl 2014-04-03/16:20:28 [com.pwc.fdb.utils.DroolsUtil] INFO reading file /opt/jboss/standalone/tmp/vfs/temp2fda10626e64d1ff/voyager.war-81e2935cd45e3fc1/WEB-INF/classes/rules/TestRuleFlow.drl 2014-04-03/16:20:28 [com.pwc.fdb.utils.DroolsUtil] ERROR KnowledgeBuilderError: Unable to create Field Extractor for 'jurisdiction'Field/method 'jurisdiction' not found for class 'com.pwc.fdb.beans.Entities'
-
3. Re: Old VFS files being read.
jaikiran Apr 3, 2014 10:44 AM (in response to richard.hart)1 of 1 people found this helpfulI have no idea why JBoss needs to reload the DroolsUtil singleton.
Whatever code is using the DroolsUtil seems to be using it in a classloader in which the DroolsUtil hasn't yet been initialized. If you have access to the DroolsUtil class, just add a few debug kind statements like:
Thread.dumpstacktrace(); // to see the code path
System.out.println("Classloader of DroolsUtil is: " + this.getClass().getClassLoader());
in the initializeKnowledgebase method of that class.
-
4. Re: Old VFS files being read.
richard.hart Apr 4, 2014 10:44 AM (in response to jaikiran)Thank you for your response.
I am starting to see a pattern in the log files. As I mentioned, we use Jenkins to build and deploy. I am beginning to think the issue revolves around the use of Jenkins. After doing a manual build, everything works fine. However, after some time, old drools rules files are read. I look in the log file and find this entry:
14:50:43,767 INFO [hudson.model.Run] (Executor #0 for master : executing vger #132) vger #132 main build action completed: UNSTABLE
14:50:47,654 INFO [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/voyager]] (MSC service thread 1-1) Cleaning up Shiro Environment
14:50:48,145 INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) JBAS015877: Stopped deployment voyager.war in 498ms
14:50:48,149 INFO [org.jboss.as.server.deployment] (MSC service thread 1-4) JBAS015876: Starting deployment of "voyager.war"
Thereafter old drools rules files are read until a manual build is performed.
I have added your suggested log entries. Nothing unusual is found with threads. I went so far as to make the class no longer a singleton but still have the same issue.
-
5. Re: Old VFS files being read.
richard.hart Apr 7, 2014 3:43 AM (in response to richard.hart)I have the issue solved now. It was a Jenkins configuration I had nothing to do with that was incomplete for a test project that was building a voyager.war file. It was not fetching from Git repository and so was building a war file with old data.
Thank you for your assistance.