Python calls Java code, finished jbpm workflow application

Source: Internet
Author: User

1. Reason

There is a huge Python Django WebProject, to introduce a workflow engine, like OA. Easy Process Control and management. Python or Django's open source plugin for workflows, which is sparse and weak, finally chooses Java's open-source framework jbpm. In order for Pythonproject to integrate the Java framework, try to jbpm-console the REST, and finally choose Python to call Java code directly. Operation JBPM.


1.1pythonprojectrest interaction with JBPM Workbench failed

REST URL Format

http://host:8080/jbpm-console/rest/runtime/ {deploymentId} /process/ {processDefId} /start

Like what

Http://localhost:8080/jbpm-console/rest/runtime/com.fun:test:1.0.0/process/test.TaskData/start
Andnot as the /runtime document says .。 The rest interface is provided by the Jbpm-console.war subproject, and this project must be deployed.

reason for failure : The process is complex and complex data needs to be handled, JBPM can build a data model internally, use Pojo to pass or store complex data, but the rest interface cannot post data in some format. So that jbpm-console self-mapping to Pojo, assuming that they write Java code to implement rest data Pojo, the feasibility of it, since they have written Java code. It is not necessary to take rest, the network is slow. JBPM logic is not as straightforward as Java code completion.

For example: JBPM creates a data model person, as

public class person{        String name = null;        int age = 0;        Boolean isman= false;}
The rest interface is not able to post data so that JBPM can be mapped to an instance of the person class, and the default jbpm-console is treated as three scattered variables (parameters), not three properties of an object. So by default, the Variableinstancelog table in the database is stored in three rows of records, each representing a variable. Not achieve the desired results. There is only one record, which only saves the serialized information of an object.

Assuming that a great God knows how to post data (or Python simply processes the post data before sending a request), Jbpm-console can proactively map to Pojo. Please leave a message. Ming Xie!


2.Python calling Java directly

2.1 Jpype not used

    • Pit (can people to avoid)
      • When a Java method or property is Pythonkeyword, you cannot access
      • Unable to access Java code that is not in the package (default package)
    • Disadvantages

      • Suitable for Python26. Real 27 version number starts JVM failure

      • Java special methods are not supported, such as Java.lang.Class.forName (String classname), mishap (because this method is very frequent in the framework/container code)

      • Unable to instantiate anonymous inner class. Only static internal classes can be instantiated

      • Thread synchronization: Understand support Synchronized class synchronization, notify, Notifyall, wait, etc. not mentioned how to deal with

      • Clear indication of a greater performance impact: can impose rather large performance bottlenecks

2.2 PyjniusUse

    • Strengths

      • Excellent package. No special Java syntax or advanced mechanism restrictions are found in the document (see also support for overloading)

      • Used in Python's own initiative to test Android applications, with a higher degree of Java language affinity

      • Abstract class/interface that supports Python inheritance/implementation Java (static members in interfaces are not supported)

      • Provide a near-universal autoclass. Reflection of a Java class proxy (can implement Java's proxy class at Python level)

    • Disadvantages

      • Windows installation is very difficult, no precompiled version number, it is expected that GCC (MinGW, vs08, Vs10 fail)

3.python<-->java se <-->jbpm <-->hibernate<-->mysql principle Brief

    • Use Pyjnius connect Python and Java

    • Java SE code uses CLASSPATH include jbpm jars and hibernate jars (must do before import Pyjnius)

    • JBPM uses hibernate in step

      • JBPM uses jbpm.proporties to setup and registers DataSource in specified db (we specify MySQL)

      • JBPM calls hibernate to operate DB, but hard code to act like use H2 DB, we force Hibernate act as use MySQL by passing Custom params when create it's entiy Manager (more details in code)

    • Hibernate operates DB, I have find a-to directly control it's behavior completely, transparently

    • Codes speak louder. More details in example.



4. Python and Java code included

Full Project code address http://download.csdn.net/detail/secretx/7814991


3.1Python Code

#coding =utf8import Osjavapath = "/home/luodh/workspace/jbpm-6.0.0.final-bin/*:/home/luodh/workspace/ jbpm-6.0.0.final-bin/lib/* "os.environ[' CLASSPATH '] = Javapath" "" Call Java code directly "" from Jnius Import Autoclassprocessmain = Autoclass (' Com.sample.ProcessMain ') #. Divide processmain.pythoncallmestatic () #ok, before Proce Ssmain (), can call Java static method# processmain.pythoncallmeinstance () #error, before Processmain (), can not call Java Instance Methodprocess_main = Processmain () process_main.pythoncallmeinstance () process_main.pythoncallmestatic () Processmain.pythoncallmestatic () processmain.pythoncallmeinstance () # after Processmain (), Python does not distinguish Static/instance methodprint "-----------------------------------------" "" "Use a Python proxy class" "from Jnius Import Javaclass, Metajavaclass, Javamethod, Javafield class Pythonproxyjavaclass (javaclass): __javaclass__ = "Com/sample/Pro    Cessmain "#/Delimited. __metaclass__ = Metajavaclass # must be this# __javaconstructor__ = (# constructor, originating from anti-compilation # "() v", #) # constructor rule not determined, document is wrong pythoncallmestatic = Javamethod ("() v", static=t Rue) Pythoncallmeinstance = Javamethod ("() V") S1 = Javafield ("ljava/lang/string;", static=true) s2 = Javafield ("L java/lang/string; ") Pythonproxyjavaclass.pythoncallmestatic () # pythonproxyjavaclass.pythoncallmeinstance () # cannot invoke an instance method until the object is instantiated Pythonproxyjavaclass (). Pythoncallmestatic () # After instantiating an object, Python does not differentiate between static (class) methods and non-static (instance) methods Pythonproxyjavaclass (). Pythoncallmeinstance () pythonproxyjavaclass.pythoncallmestatic () pythonproxyjavaclass.pythoncallmeinstance () "" " Python strictly distinguishes between static/non-static field "" "Print pythonproxyjavaclass.s1# print Pythonproxyjavaclass.s2 # Error, class does not bind to member variable print Pythonproxyjavaclass (). S1 # None, the instance is not bound to the static variable print pythonproxyjavaclass (). S2

3.2 Java code (JBPM related)

Package Com.sample;import Java.util.hashmap;import java.util.list;import java.util.map;import java.util.Properties; Import Javax.persistence.entitymanagerfactory;import Javax.persistence.persistence;import Org.jbpm.test.jbpmhelper;import Org.kie.api.kiebase;import Org.kie.api.kieservices;import Org.kie.api.runtime.kiecontainer;import Org.kie.api.runtime.kiesession;import Org.kie.api.runtime.manager.runtimeengine;import Org.kie.api.runtime.manager.runtimeenvironmentbuilder;import Org.kie.api.runtime.manager.runtimemanager;import Org.kie.api.runtime.manager.runtimemanagerfactory;import Org.kie.api.task.taskservice;import Org.kie.api.task.model.tasksummary;public class ProcessMain {public static string S1 = "I ' m static field";p ublic string s2 = "I ' m instance field";p ublic static Runtimemanager manager = Null;public static void Main (string[] args) {calljbpm (false); System.exit (0);} public void Pythoncallmeinstance () {calljbpm (true);} public static void Pythoncallmestatic () {calljbpm (true);} Public static void calljbpm (Boolean fake) {if (fake) {System.out.println ("I ' m Java, Python call me to play jbpm. I don ' t know how to include jbpm jars. "); return;} Kieservices KS = KieServices.Factory.get (); Kiecontainer Kcontainer = Ks.getkieclasspathcontainer ();//load Kmodule.xmlkiebase kbase = kcontainer.getkiebase ("Kbase" )///based on the exposed name (the name attribute of the kbase tag) gets the Repository object if (manager = = null) {manager = Createruntimemanager (kbase);//Use synchronized static Block}runtimeengine engine = Manager.getruntimeengine (null); Kiesession ksession = Engine.getkiesession (); Taskservice Taskservice = Engine.gettaskservice ();/engine altogether 3 interfaces getauditlogserviceksession.startprocess (" Com.sample.bpmn.hello ");//Let John execute Task 1list<tasksummary> list = Taskservice.gettasksassignedaspotentialowner ("John", "En-uk"); Tasksummary task = list.get (0); System.out.println ("John is executing task" + task.getname ()); Taskservice.start (Task.getid (), "John"); Taskservice.complete (Task.getid (), "John", null);/Let Mary Execute task 2list = Taskservice.gettasksassignedaspotentialowner ("Mary", "En-uk"); task = List.get (0); System.out.println ("Mary is executing task" + task.getname ()); Taskservice.start (Task.getid (), "Mary"); Taskservice.complete (Task.getid (), "Mary", NULL), Manager.disposeruntimeengine (engine);//system.exit (0);} private static Runtimemanager Createruntimemanager (Kiebase kbase) {//Because to get a task, you need to taskservice the storage operation, need to start the database in advance, prepare the data source// Jbpmhelper.starth2server ();//Do not H2, do not start jbpmhelper.setupdatasource (); map<string, string> map = Confighibernate (); Entitymanagerfactory emf = persistence.createentitymanagerfactory ("ORG.JBPM.PERSISTENCE.JPA", map); Runtimeenvironmentbuilder builder = RuntimeEnvironmentBuilder.Factory.get (). Newdefaultbuilder (). Entitymanagerfactory (EMF). Knowledgebase (Kbase); return RuntimeManagerFactory.Factory.get (). Newsingletonruntimemanager (Builder.get (), "com.sample:example:1.0");//any_non_blank_string}private static Map< String, string> confighibernate () {map<string, string> Map = new HashMap<string, string> ();        Properties Properties = new properties ();        try {properties.load (JBPMHelper.class.getResourceAsStream ("/jbpm.properties")); } catch (Throwable t) {//Do nothing, use defaults} map.put ("Hibernate.dialect", Properties.get Property ("Hibernate.dialect", "Org.hibernate.dialect.MySQL5Dialect"), Map.put ("Hibernate.hbm2ddl.auto", Properties.getproperty ("Hibernate.hbm2ddl.auto", "Update"), Map.put ("Hibernate.show_sql", Properties.getproperty ("Hibernate.show_sql", "false")); Map.put ("Hibernate.format_sql", Properties.getproperty ("Hibernate.format_sql", "true")); return map;}}




Python calls Java code, finished jbpm workflow application

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.