→ L’instruction importClass génère une erreur InternalError: Function importClass must be called with a class; had "[JavaPackage com.simplicite.commons.RenaultAPI.DBBToolBox]" instead et sans l’instruction importClass, l’usage de DBBToolBox génère l’erreur ReferenceError: "DBBToolBox" is not defined (ça ne marche pas non plus avec le path complet com.simplicite.commons.RenaultAPI.DBBToolBox).
Je mettrai juste l’import du package en début de script, en dehors de la fonction importPackage(Packages.com.simplicite.commons.RenaultAPI);
pas d’import de class contenue dans le package.
et publish n’étant pas static, il faut plutôt faire un new DBBToolBox().publish(...)
Si cela ne fonctionne pas c’est que Rhino ne s’exécute pas dans le même class*loader que les classes des modules, il faudra voir comment faire en V4 ou passer en V5 et faire du full-java
Merci beaucoup pour ta réponse rapide. J’ai essayé sans succès de remonter l’instruction d’import au début du script.
Je bloque sur ce point car je dois publier des events via AMQP (apache.qpid) pour plus de 20 objets qui sont encore en Rhino (~5000 à 8000 lignes de code pas très bien commenté) et que le code partagé Rhino que j’ai écrit pour réalisé des publications cesse de fonctionner à un moment donné apparemment du fait d’un problème de proxy qu’il est possible de résoudre en injectant un proxy socks dans les extensions de la JmsFactory… Je sais le faire en Java mais pas en Rhino (le mécanisme s’appuie sur un Supplier de fonction que je n’arrive pas à mettre en oeuvre en Rhino).
La solution du full-java est en effet la plus pérenne mais elle n’est (pour l’instant) pas compatible avec mon plan de charge (la réécriture a commencé mais j’ai encore 80% des objets de mon modèle implémentés en Rhino ; et accessoirement, j’apprends le Java en passant ). Et la réutilisation du code partagé Java était une des options que j’avais envisagé pour dérouler progressivement la phase de ré-écriture en java.
Tu as évoqué un problème de classloader → je pense que c’est ça… Je ne sais pas si je peux intervenir à ce niveau.
Je vais faire des essais en V4 sur une classe simple, car ça devrait marcher en théorie.
Si la classe ou le package ne se charge pas (le message Rhino est assez flou), ça peut aussi être un problème de dépendances avec des libs tierces.
Je viens de tester en commentant tout le code qpid et les imports afférents (il ne reste plus que les imports standards Simplicité) et ça ne fonctionne toujours pas…
Je reproduis bien le problème qui vient bien du classloader de Rhino qui n’est pas celui dynamique de Simplicité qui contient les JAR des modules + shared code en LIB partagées…
On va revoir ça pour recharger si possible un nouveau ScriptEngineManager à chaque compilation.
Après quelques tests, il ne semble pas possible de changer de classloader pour Rhino, il ne trouve toujours pas les classes, il doit y avoir des choses chargées dans la JVM/tomcat qu’on ne peut plus modifier à chaud.
Il faut donc revenir à des choses plus prédictives en faisant de la reflexion Java, c’est plus verbeux mais on peut appeler des méthodes dynamiquement dans n’importe quel CL comme ceci :
Exemple :
package com.simplicite.commons.Demo;
public class DemoCommon {
public DemoCommon() { /* empty constructor */ }
public String test(Grant g) {
return "Hello world = " + g.getLogin();
}
}
Appel en Rhino :
// Il faut accéder au CoreCache qui contient le CL dynamique
importPackage(Packages.com.simplicite.util.engine);
DemoSupplier.preSave = function() {
var g = this.getGrant();
// Class dynamique dans le module Demo
var cls = CoreCache.getInstance().getClass("com.simplicite.commons.Demo.DemoCommon");
// Constructeur vide
var obj = cls.newInstance();
// Methode à appeler avec les Class des arguments
var method = cls.getMethod("test", g.getClass() /*, ... */);
// Invoke dynamique avec les paramètres
var ret = method.invoke(obj, g /*, ... */);
return "Result = " + ret + "#INFO";
};