Erreurs lors de l’appel d’un script partagé en Rhino

Bonjour,

Je rencontre depuis qq jours un souci avec un script partagé, uniquement sur les instances du serveur Simplicité.

Exemple instance Simplicité :

Lors de son appel depuis le script d’un objet, j’obtiens l’erreur :

org.mozilla.javascript.EcmaError: ReferenceError: "ImmoJobProperty" is not defined.

Ce même script ne pose pas de pb sur les instances du serveur OVH, qui ne sont pas à jour.

Exemple instance OVH :

J’ai bien sûr essayé de faire des clears caches, arrêt/redémarrage de l’instance, purge…. Le résultat est le même.

J’essaie de mettre en commentaire le code et d’avancer étape par étape sur une instance du serveur Simplicité et je trouve que le script passe bizarrement en erreur quand j’ajoute simplement la déclaration de la variable suivante (qui se trouve à la ligne 660 du script !) :

var strategProAnnuiteEstimA = rent.getField("strategProAnnuiteEstim");

Sachant que l’attribut existe bien dans l’objet en question.

Il suffit que je mette en commentaire cette ligne pour que le script avance aux lignes suivantes, avant de replanter à nouveau sur d’autres lignes, qui sont aussi normales que celle de dessus.

C’est très bizarre et je ne trouve aucune explication à cela.

Je ne sais pas si j’arrive à bien expliquer mon problème.

Auriez-vous une idée ?

Merci d’avance pour votre retour.

Abed.

Le passage en JDK 16 a obligé à changer le composant d’encapsulation du moteur Rhino (l’ancien n’était pas compatible avec ce JDK).

Nous n’avons pas constaté d’effet négatif de ce changement sur nos cas de test mais il y a peut être des cas aux limites plus subtils. Nous allons essayer de reproduire le pb.

J’ai fait un test le plus basique possible sur une 4.0 à jour:

[Platform]
Status=OK
Version=4.0.P25
BuiltOn=2021-04-08 00:30 (revision 14e9b3f2cdf8dc7c3b50fa494fa35ac497c6d009)

J’ai créé un code partage Rhino AppCommon avec le code suivant:

var AppCommon = AppCommon || (function() {
	function hello(g) {
		return "Hello " + g.getLogin();
	}
	
	return { hello: hello };
})();

Et un objet métier AppTest avec un “shared code usage” sur le code partagé ci-dessus et le code suivant:

AppTest.postLoad = function() {
	console.log(AppCommon.hello(this.getGrant()));
};

Lors du 1er accès à cet objet je vois bien la trace :

Sur un cas basique et nominal comme celui là il n’y a pas de pb dans la “mécanique” d’utilisation d’un code partagé depuis un objet métier. Vous devez donc être dans un cas plus complexe…

Le module de test: Application-0.1.zip (2.5 KB)

Pas de pb non plus en accédant aux valeurs d’un field de l’objet dans le code de l’objet:

AppTest.initUpdate = function() {
	console.log(this.getFieldValue("appTstCode") + " " + AppCommon.hello(this.getGrant()));
};

Je suis d’accord avec vous que c’est un cas plus complexe, puisque le pb apparaît seulement à partir de la ligne 660. c’est à dire, si je laisse le reste du script en commentaire (tout ce qui est après la lignes 660), le script partagé fonctionne bien. mais quand j’ajoute la simple déclaration de variable, le script passe en mode “not define” sans plus d’information dans la log.

Pour qu’on puisse investiguer votre cas particulier il faut essayer de le reproduire dans le contexte le plus simple possible.

Il y a peut être de “mauvais” patterns quand on écrit du code Rhino qui marchaient peut être mais que le changement de composant d’encapsulation du moteur Rhino a mis en lumière.

Sur les cas qu’on a testé on a pas vu de différence mais on y fait des choses relativement simples.

Que puis-je vous communiquer pour que vous puissiez le reproduire dans un contexte simple ?

On peut faire si vous voulez une visio avec partage d’écran.

Mon script, qui fait plus de 850 lignes, plante à partir de la ligne 660, les 660 premières lignes passent sans pb, l’ajout d’une simple déclaration de variable pose pb ! et le pire que le message d’erreur n’est pas du tout parlant.

Je suis à votre disposition pour toute info ou action nécessaire de mon côté afin de régler ce gros point de blocage.

Ca ne me dit rien du tout, il y a peut être une limitation sur la taille d’un script en mémoire à 64k ou quelque chose de cet ordre qui tronque le script.

Essayez de couper votre script en 2.
Quelles sont les stacktraces exactes dans les logs ?

Merci @Francois .
En découpant le script en 2, je n’ai plus d’erreur. Bizarrement, un autre script partagé qui compte plus de 1000 lignes et qui est appelé à partir d’un autre objet, fonctionne normalement et pas besoin de découpage !

L’erreur qui s’affichait était :

2021-04-09 11:27:17,525 INFO [com.simplicite.objects.System.Script] SIMPLICITE|http://e3m.simplicite.io:10188||INFO|system|com.simplicite.objects.System.Script|partialClearCache||Evénement: Partial clear cache for shared code ImmoJobProperty
2021-04-09 11:26:20,519 ERROR [com.simplicite.util.RhinoScriptInterpreter] SIMPLICITE|http://e3m.simplicite.io:10188||ECORESC002|designer|com.simplicite.util.RhinoScriptInterpreter|ImmoProperty.postValidate||Erreur évaluation script: ImmoProperty
    org.mozilla.javascript.EcmaError: ReferenceError: "ImmoJobProperty" is not defined. (ImmoProperty#635) in ImmoProperty at line number 635
    line 630: /// Calcul le Total des TF non récupérable, les loyers encaissés / an et Valeur locative estimée
    line 631: /// Calcul du Rendement Secteur en fonction du code postale s'il existe sinon, code département:
    line 632: /// Calcul de la Notation Rendement du bien :
    line 633: if (!this.isNew()) {
    line 634: console.log("Appel méthode ImmoProperty_CalculIndicateurs"); // + this.getInstanceName());
    error635: ImmoJobProperty.ImmoProperty_CalculIndicateurs(this,this.getGrant(),0);
    line 636: }
    line 637: // Warninng : Si le taux d’occupation > 100%, on demande de vérifier les surfaces des lots loués.
    line 638: var a1 = this.getField("strategProOccupancyRate");
    
2021-04-09 11:26:20,519 INFO [com.simplicite.util.ScriptInterpreter] SIMPLICITE|http://e3m.simplicite.io:10188||INFO|designer|com.simplicite.util.ScriptInterpreter|ImmoProperty/the_ajax_ImmoProperty||Evénement: Appel méthode ImmoProperty_CalculIndicateurs

ImmoJobProperty est le nom du script partagé que j’ai du découpé

J’ajoute juste une info supplémentaire :
Le script qui posait pb avant découpage, fonctionne très bien, sans découpage en V5.1 !!!

Je ne pense pas que le pb soit lié à la taille du fichier mais plutôt à un pb de code (une erreur comme ReferenceError: "xxx" is not defined. signifie qu’à cet endroit du code xxx n’est pas définie dans le scope, peut être faudrait il utiliser plutôt this à cet endroit ou dans le genre).

Je doute aussi que le changement de composant de “wrapping” de Rhino en script engine JSR223 ait changé quelque chose (ce composant de wrapping n’est pas géré dans le code Simplicité mais uniquement par la JVM pour trouver l’engine nommé “rhino”).

La lib Rhino, elle, n’a pas changée depuis très longtemps sur la 4.0 maintenance. Sauf obligation impérieuse (comme pour le composant ci-dessus) on n’upgrade jamais les libs sur les versions releasées.

En 5.x c’est une version plus récente de la lib Rhino (1.7.13 vs 1.7.11 en 4.0), si on parle d’instances SIM on peut éventuellement faire le test d’upgrader manuellement cette lib pour voir si ça change quelque chose.

Cf la changelog de Rhino rhino/RELEASE-NOTES.md at master · mozilla/rhino · GitHub, depuis la 1.7.11 il y a visiblement eu de nombreux “fixes”.

Je ne suis pas expert Rhino mais il peut y avoir des erreurs de compilation dans les logs du style:

generated bytecode for method exceeds 64K limit

Ensuite au runtime forcement ça peut faire n’importe quoi.

Vos fonctions “communes” pourraient dans un premier temps migrer en Java via des méthodes static, et ne plus passer par du script partagé. C’est à 90% le même code, il faut juste typer les variables + créer une classe de méthodes static.

Sur le fond, on en revient toujours au même sujet de vouloir tout coder en Rhino au delà de scripts interprétés “élémentaires” (contrainte, expression calculée…) = risque d’avoir des problèmes bloquants plus complexes à investiguer/résoudre que de migrer vers du Java beaucoup plus robuste, rapide et simple à debugger.

Oui, les instances qui posent pb pour l’instant sont sur le serveurs Simplicité, et donc, sur SIM. Les autres instances sur OVH ne sont pas encore à jour.

Oui, je veux bien que fassiez le test d’upgrade pour voir si cela change qq choses.

Faut-il faire qq choses de notre côté ?

Merci d’avance @david

Non je vais m’en occuper, dites moi juste sur quelle instance vous voulez que je fasse la manip.

sur l’instance conjonctiondevnat, ensuite je remets le script partagé avant découpage et je ferai le test.

@françois,

La seule erreur que je vois dans le log est celle que j’ai citée ci-dessus. Je ne regarde peut-être pas le bon log pour les erreurs Rhino ?

Pour ce qui est de la migration Rhino vers Java, ce n’es malheureusement pas encore à l’ordre de jour, même pas pour un script partagé, car si mes souvenirs sont bons, c’est déconseillé de migrer un composant d’un objet sans migrer la totalité de ses composants. L’objet en question possède son propre script (1500 lignes) et fait appel à 6 scripts partagés dont un fait plus de 2500 lignes et utilisé par des dizaines d’autres objets.

Donc s’il y a une solution (celle proposée par David par exemple) qui nous permet actuellement de revenir à une situation stable (comme c’était le cas il y a qq jours), je suis preneur.

Done

J’ai remis le script partagé en entier et cela fonctionne très bien !!!

Merci @david

Pourriez-vous faire la même chose avec les autres instances de SIM :
conjonctiondev
conjonctiondevtmp

Pourriez-vous nous indiquer svp comment peut-on faire cette manip sur les instances qui sont sur le serveur OVH ? (@Paul_S )

Merci encore.

On ne va rien faire de plus manuellement.

On va upgrader la lib Rhino sur la branche de maintenance 4.0 et ce sera poussé au prochain build (i.e. ce soir) donc dès demain ce sera dispo sur les serveurs SIM et dans les images Docker simplicite/platform:4.0*

Parfait.
Il faudra donc juste qu’on mette à jour les images Simplicités sur OVH à partir de demain.