BundleUtil and Scripting Hints in Designer

I'm adding some scripting hints to my designer, and trying to put the script methods in an interface rather than an abstract class (I will only have a gateway representation of this class and am using a Proxy/Invocation handler on the designer side).

I'm using the debugger and see my .properties file loaded into the BundleUtil, but I can't seem to get scripting hints to work?

I have 2 questions really:

  1. I'm initializing these bundles in a for loop inside of the initializeScriptManager method in my designer hook. Is that ok or does that maybe need to happen in setup or startup?
  2. What's the exact key that scripting hints will be looking for? I'm finding my {docBundlePrefix}.{methodName}.param.{scriptArg} keys, but wanted to make sure I have the format correct on that...

Generally, our scripting function implementations register with bundle util in a static block inside them, which would imply deferral until they're actually constructed, so this should be fine; see AbstractScriptModule in our public SDK:

Exact format depends slightly on if your method is accepting keyword arguments (a PyObject[], String[] signature) or regular Java arguments, but that looks correct to me.

Something like the below, where docBundlePrefix is implicit (not actually part of your properties file), ex:

1 Like

While I'm here, I guess I'll also advertise that this system gets a lot more depth in 8.3, and a proper documentation pass:

This'll be fully backwards compatible (in that old property keys will continue to work) but with a ton of progressive enhancement available.

4 Likes

Right, so I found my issue and it's basically because I'm trying to do something "special" with Java's Proxy/Invocation Handler API so that I force everything from a designer to be an RPC call to the gateway and only implement the methods there (I only plan on supporting Perspective, so these scripting methods will be purely in designer to play with/debug in the script console).

I ended up extending the PropertiesFileDocProvider to return methods directly from the interface class (which have the @ScriptFunction annotation) instead of using the Proxied instance.

Thanks for your help Paul!

Why are you reinventing this wheel? It's already what ModuleRPCFactory does, and the scripting example in the SDK repo shows how it's used.

At first it was to proxy 20 different script classes through the single RPC interface. I can have an invocation handler on the designer side that wraps/sends the info as an RPC request and then my RPC handler on the gateway can route that request through to the implementation and return the result.

Also, it's saving me from defining any client side classes. I have interfaces in my common scope, a proxy in the designer scope and all implementation is done in the gateway scope (because that's where all my services/business logic reside anyway). So I don't have any kind of client/designer implementation of the classes at all.

I know the multiple RPC handlers will be resolved in 8.3, but am I misunderstanding something and making it way too complicated?

Consider not doing this at all. Particularly if you can use my @runInGateway decorator. You don't want a single script in the designer to call your API in a loop or something like that, yielding many round trips.

For separation of concerns, I'd strongly recommend _de_coupling the scripting interface from the RPC interface. I literally just drew up this diagram yesterday:

Your common scope should define the scripting interface - whatever public facing functions you want to expose via scripting. This is also where you can put your properties files and your argument handling logic.
Then, once you've unpacked whatever Jython signature into basic Java primitives or module specific objects or whatever, delegate to abstract impl methods or a passed in interface or whatever.

It's really tempting to have your scripting interface directly act as your RPC interface, and it'll work...until it doesn't, and untangling the two things becomes something you have to spend a lot of effort doing down the road. Ask me how I know :smile:

If you use something like the ModuleRPCFactory Kevin mentioned above and this decoupling I advise (most crucially, being very aware of what types you're sending over the RPC bridge), your migration to 8.3 will be very smooth.

3 Likes