I worked on a warehouse management system where we moved from C++/PLSQL to J2EE solution with JBPM 3 library (it's a java library that implements graphical language - looked like this [1]). It was very good fit for our system, but it still had lots of problems.

The tooling was pretty bad (it was a plugin for older version of eclipse, had pretty bad bugs). We added our functionality to that plugin, and these were big usability wins, but also it made the plugin even less stable.

Sometimes the graphical editor would "desynchronize" and if you haven't noticed you could be editing the process in graphical editor for 2 hours, but the XML file would remain unchanged (or even broken).

So developers became paranoid about changing to the XML view every few seconds to check, or they just edited the XML directly all the time :)

We had problems with several things that are solved in regular languages. For example there were subprocesses (analog of functions) - you could invoke a subprocess, pass arguments, wait for it to end, and receive return values from the subprocess. That solved problem of duplication of common functionality, but also required us to add support for pretty complex mappings when invoking subprocesses.

For example we had a node that does a HQL query and shows the results in table on the user terminal. These queries were parametrized, and some parameters were constant in each process, just changed between processes. So we added a way to specify these parameters. Then there were some processes where it would be useful to specify additional conditions for a query in the graphical editor. So we added that.

Then it would be useful to pass around that conditions between subprocesses, and fill some parameters there in some subprocesses, while the others remain to be filled by the app server.

It was much too complex (I am mostly to blame - I was straight out of university and was amazed by this cool technology and wanted to add all the bells and whistles I could think of :) ).

What we should do instead is just duplicate the subprocesses with different conditions, or construct these conditions in java code on app server and just call that from the graphical designer.

Eventully like half of all our business logic was encoded in the nodes that invoked subprocesses in the mapping between inner and outer process variables.

The other half was mostly in the conditions on transitions between the nodes.

Both of these things weren't visible when you looked at the whole graph - transitions only showed labels (which were sometimes outdated vs the REAL condition code), and the invoke process nodes showed nothing until you clicked on them.

So when you had a big process with 40 nodes you had to click on each node (and scroll through sometimes 30 mappings) to see "who set that variable".

Same with transitions - you had to click on each transition to see the conditions.

We tried to show the conditions in the main view but it wasn't easily changed in that plugin.

Overall I think the graph language was great, the automatic transaction and persistence support was the best things about it, but the visual programming aspect of it was rarely useful, and very often problematic.

I would now go the other way - have the graph language be text-first (with some nice DSL), and rendered to a nice graphical view on-demand.

Better tooling could probably help, but we spent maybe 3 man-years on fixing and improving that plugin and it never worked great.

[1] https://docs.jboss.org/tools/whatsnew/jbpm/images/multiple-p...