简体   繁体   English

Drools KieContainer 不会使用自定义类加载器触发规则

[英]Drools KieContainer does not fire rules with custom classloader

I am trying to add a non-existing method to a Java bean, compile it and use the newly added method in Drools rules.我正在尝试向 Java bean 添加一个不存在的方法,对其进行编译并使用 Drools 规则中新添加的方法。 Via a custom class loader.通过自定义类加载器。

I am using CompilerUtils to bind newly modified class to the custom ClassLoader as follows:我正在使用CompilerUtils将新修改的类绑定到自定义ClassLoader ,如下所示:

        ClassLoader loader = new ClassLoader(){};

        String className = "com.example.Transaction";

        String path = "file:D:/workspace/Transaction.class.tmp"; // a tmp file that contains source for Java bean

        try {

            URL transactionUrl = new URL(path);

            URLConnection connection = transactionUrl.openConnection();

            InputStream input = connection.getInputStream();

            String transactionClass = new String(StreamUtils.copyToByteArray(input), StandardCharsets.UTF_8);

            System.out.println(transactionClass);

            String javaCode = "\npublic int test() {\n" +
                    "        return 3;\n" +
                    "    }\n" +
                    "}";

            String updatedClassString = transactionClass.substring(0, transactionClass.length() - 1).concat(javaCode);

            Class<?> classB = CompilerUtils.CACHED_COMPILER.loadFromJava(loader, className, updatedClassString); // This is where the loader is made aware of the newly compiled class
            
            return loader;


        } catch (IOException | ClassNotFoundException exception) {
            e.printStackTrace();
        }

        return null;

And this is where I give access to drools my classloader这就是我允许我的类加载器访问流口水的地方

   
        final KieServices kServices = KieServices.Factory.get();
        final KieFileSystem kFileSystem = kServices.newKieFileSystem();

        final KieModuleModel kModuleModel = KieRulePopulator.kieModuleModel();
        if (kModuleModel != null) kFileSystem.writeKModuleXML(kModuleModel.toXML());

        kServices
                .newKieBuilder(kFileSystem, classLoader)
                .buildAll();
        }

        KieContainer container = kServices.newKieContainer(kServices
                .getRepository()
                .getDefaultReleaseId(), classLoader);

This is how I fire rules这就是我触发规则的方式


       final KieBaseConfiguration configuration = KieServices.Factory.get().newKieBaseConfiguration();

       final KieSession kSession = container
                .getKieContainer()
                .newKieBase(configuration)
                .newKieSession();

Transaction someTransaction = new Transaction();

kSession.insert(transaction);
kSession.fireAllRules();
    

And this is my rule这是我的规则

    rule "Rule_31F6DE769554404B89D4E3B7B5979CA1"
    dialect "java"
    no-loop true
    
    when
        tr : Transaction( test == 3 )

    then
        System.out.println("deneme");
    end

I have load Transaction class from containers classloader and it worked.我从容器类加载器加载事务类并且它工作。

final KieSession kSession = container
                .getKieContainer()
                .newKieBase(configuration)
                .newKieSession();

Class<?> classA = container.getKieContainer().getClassLoader().loadClass("com.example.Transaction");

Object transaction = classA.getDeclaredConstructor().newInstance();

kSession.insert(transaction);
kSession.fireAllRules();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM