Uploaded image for project: 'JBRULES'
  1. JBRULES
  2. JBRULES-3283

Concurrency issue: Invalid bytecode generated by KnowledgeBuilder.add()

    XMLWordPrintable

Details

    • Hide

      Perform parallel operation of adding resources to different knowledgebuilders:

      public static KnowledgeBase readKnowledgeBase(final String resource) throws Exception
          {
              final Reader source;
              final String fileName = "/" + resource + ".drl";
      
              InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
              if (inputStream == null)
              {
                  inputStream = new FileInputStream("src/main/resources" + fileName);
              }
              source = new InputStreamReader(inputStream, "UTF-8");
      
              final Properties props = new Properties();
              props.setProperty("drools.dialect.java.compiler", "JANINO");
              props.setProperty("drools.dialect.java.compiler.lnglevel", "1.6");
              KnowledgeBase result;
      
              final KnowledgeBuilderConfiguration configuration = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(props, RuleUtil.class.getClassLoader());
              final KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(configuration);
      
              Resource newReaderResource = ResourceFactory.newReaderResource(source);
              //synchronized (RuleUtil.class)
              {
                  builder.add(newReaderResource, ResourceType.DRL);
              }
              result = builder.newKnowledgeBase();
      
              return result;
          }
      
      Show
      Perform parallel operation of adding resources to different knowledgebuilders: public static KnowledgeBase readKnowledgeBase( final String resource) throws Exception { final Reader source; final String fileName = "/" + resource + ".drl" ; InputStream inputStream = Thread .currentThread().getContextClassLoader().getResourceAsStream(fileName); if (inputStream == null ) { inputStream = new FileInputStream( "src/main/resources" + fileName); } source = new InputStreamReader(inputStream, "UTF-8" ); final Properties props = new Properties(); props.setProperty( "drools.dialect.java.compiler" , "JANINO" ); props.setProperty( "drools.dialect.java.compiler.lnglevel" , "1.6" ); KnowledgeBase result; final KnowledgeBuilderConfiguration configuration = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(props, RuleUtil. class. getClassLoader()); final KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(configuration); Resource newReaderResource = ResourceFactory.newReaderResource(source); // synchronized (RuleUtil.class) { builder.add(newReaderResource, ResourceType.DRL); } result = builder.newKnowledgeBase(); return result; }
    • Hide

      Synchronize access of KnowledgeBuilder.add()

      Show
      Synchronize access of KnowledgeBuilder.add()

    Description

      Since Drools 5.3.0.CR1 concurrent creation of different knowledgebases from filesystem DRL rule definition leads to illegal bytecode.
      Reproduceable with Janino and eclipse compiler.

      I have a maven based test project which executes the unit tests in parallel, this is the result:

      runFirst(de.trion.drools53.TwoTest): -1
        runFirst(de.trion.drools53.FourTest): (class: de/trion/drools53/Rule_When_a_user_is_young__print_his_name_DefaultConsequenceInvoker, method: equals signature: (Ljava/lang/Object;)Z) Expecting to find integer on stack
        runSecond(de.trion.drools53.FourTest): (class: de/trion/drools53/Rule_When_a_user_is_young__print_his_name_DefaultConsequenceInvoker, method: equals signature: (Ljava/lang/Object;)Z) Expecting to find integer on stack
        runFirst(de.trion.drools53.OneTest): (class: de/trion/drools53/Rule_When_a_user_is_young__print_his_name_DefaultConsequenceInvoker, method: equals signature: (Ljava/lang/Object;)Z) Expecting to find integer on stack
        runFirst(de.trion.drools53.ThreeTest): (class: de/trion/drools53/Rule_When_a_user_is_young__print_his_name_DefaultConsequenceInvoker, method: equals signature: (Ljava/lang/Object;)Z) Incompatible object argument for function call
        runSecond(de.trion.drools53.ThreeTest): (class: de/trion/drools53/Rule_When_there_is_god__the_light_always_shines_DefaultConsequenceInvoker, method: equals signature: (Ljava/lang/Object;)Z) Unable to pop operand off an empty stack
      

      Workaround: synchronize access
      Not affected: Drools 5.3.0.Beta

      Attachments

        Issue Links

          Activity

            People

              mfusco@redhat.com Mario Fusco
              evrflx Thomas Kruse (Inactive)
              Votes:
              2 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: