{"record":{"id":"db5a0b514f849af6","repo":"pentaho/pentaho-kettle","slug":"rulesdata-error-compiledrl-db5a0b","errorCode":"RulesData.Error.CompileDRL","errorMessage":"RulesData.Error.CompileDRL","messagePattern":"RulesData\\.Error\\.CompileDRL","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"plugins/drools/core/src/main/java/org/pentaho/di/trans/steps/rules/RulesExecutorData.java","lineNumber":107,"sourceCode":"\n  public void initializeRules() {\n\n    // To ensure the plugin classloader use for dependency resolution\n    ClassLoader orig = Thread.currentThread().getContextClassLoader();\n    ClassLoader loader = getClass().getClassLoader();\n    Thread.currentThread().setContextClassLoader( loader );\n    KieServices kieServices = KieServices.Factory.get();\n    KieFileSystem kfs = kieServices.newKieFileSystem();\n    String internalFilePath = \"src/main/resources/kettle.drl\";\n\n    if ( ruleString != null ) {\n      kfs.write( internalFilePath, ruleString );\n    } else {\n      try {\n        FileInputStream fis = new FileInputStream( ruleFilePath );\n        kfs.write( internalFilePath, kieServices.getResources().newInputStreamResource( fis ) );\n      } catch ( FileNotFoundException e ) {\n        throw new RuntimeException( BaseMessages.getString( PKG, \"RulesData.Error.CompileDRL\" ) );\n      }\n    }\n    KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();\n    Results results = kieBuilder.getResults();\n\n    if ( results.hasMessages( Message.Level.ERROR ) ) {\n      System.out.println( results.getMessages() );\n      throw new RuntimeException( BaseMessages.getString( PKG, \"RulesData.Error.CompileDRL\" ) );\n    }\n\n    KieContainer kieContainer = kieServices.newKieContainer( kieServices.getRepository().getDefaultReleaseId() );\n    kieBase = kieContainer.getKieBase();\n\n    // reset classloader back to original\n    Thread.currentThread().setContextClassLoader( orig );\n  }\n\n  public void initializeColumns( RowMetaInterface inputRowMeta ) {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/drools/core/src/main/java/org/pentaho/di/trans/steps/rules/RulesExecutorData.java#L89-L125","documentation":"In RulesExecutorData.initializeRules(), when no inline rule string is set, the step opens the configured rule file with new FileInputStream(ruleFilePath); if the file does not exist, the caught FileNotFoundException is rethrown as a RuntimeException carrying the (misleading) i18n message \"RulesData.Error.CompileDRL\". Despite the message, this specific throw at line 107 is a file-not-found problem, not a DRL compilation problem.","triggerScenarios":"Calling initializeRules() on a RulesExecutorData with ruleString == null and ruleFilePath pointing to a path that does not exist or is not readable at runtime — e.g. a relative path resolved against a different working directory, a file referenced on a local disk while the transformation runs on a cluster node, or a variable in the path left unexpanded.","commonSituations":"Using ${Internal.Transformation.Filename.Directory}-style variables that are empty when run outside the repository; agent/Spoon working directory differs from the one used when configuring the step; file was moved/deleted; path points to a cluster slave where the file is absent.","solutions":["Verify the path in the Rules Executor step dialog and use an absolute path (or correct variables) — then check `new File(path).exists()` in the same environment where the transformation runs.","If variables are used, confirm they resolve at runtime (log them via a 'Write to Log' step or getVariable in a UDJC).","On clustered runs, make sure the DRL file exists at the same location on every slave node, or embed the rule inline (ruleString) instead of a file path.","Confirm file read permissions for the user running the JVM/PDI."],"exampleFix":"// before\nstepMeta.setRuleFilePath(\"rules/my-rules.drl\"); // relative, cwd-dependent\n\n// after\nstepMeta.setRuleFilePath(\"/opt/pdi/rules/my-rules.drl\"); // absolute, or embed via setRuleString","handlingStrategy":"validation","validationCode":"// Before initializeRules(), verify the rule file is readable\nString path = data.getRuleFilePath();\nif (data.getRuleString() == null) {\n  java.io.File f = new java.io.File(path);\n  if (!f.isAbsolute()) throw new IllegalStateException(\"rule file path must be absolute or resolved: \" + path);\n  if (!f.exists()) throw new IllegalStateException(\"rule file not found: \" + path);\n  if (!f.canRead()) throw new IllegalStateException(\"rule file not readable: \" + path);\n}","typeGuard":null,"tryCatchPattern":"try {\n  data.initializeRules();\n} catch (RuntimeException e) {\n  if (String.valueOf(e.getMessage()).contains(\"CompileDRL\") && data.getRuleString() == null) {\n    throw new KettleStepException(\"Rule file not found: \" + data.getRuleFilePath()\n      + \" — note the message says CompileDRL but this path is a FileNotFoundException\", e);\n  }\n  throw e;\n}","preventionTips":["Use absolute paths or resolve ${Internal.Transformation.Filename.Directory} variables","Verify variables resolve at runtime (log them before the step)","On clustered executions, ensure the DRL exists on every node, or embed the rule inline","Check filesystem permissions for the user running the PDI JVM"],"tags":["file-not-found","drools","drl","kettle","io"],"backgroundTag":"file-not-found","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}