Une part importante des défauts des applications interactives (APPL)Logiciels JD Edwards composés d'écrans permettant aux utilisateurs de consulter et modifier des données. personnalisées audités lors des mises à niveau 9.2 — selon notre expérience, environ un tiers à la moitié — provient d'erreurs classiques de séquence d'événements JDEJD Edwards : progiciel de gestion intégré (ERP) d'Oracle utilisé pour la gestion d'entreprise. APPL commises par des développeurs supposant une exécution synchrone. La cause profonde est rarement une fonction métier (BSFN)Business Function : composant logiciel réutilisable exécutant une logique spécifique sur le serveur. défectueuse ; il s'agit plutôt d'un défaut de prise en compte de la manière dont le moteur JAS (Java Application Server)Serveur gérant l'interface utilisateur web et la communication entre le client et le serveur. sérialise les événements. Lorsque les développeurs placent mal les Event Rules (ER)Langage de programmation visuel utilisé pour définir la logique applicative dans JD Edwards. dans le Form Design Aid (FDA)Outil de développement graphique permettant de concevoir les écrans et la logique des applications JDE., ils exposent les applications à des conditions de concurrence (race conditions)Bug survenant lorsque le résultat dépend de l'ordre imprévisible d'exécution de plusieurs tâches simultanées. qui ne se manifestent que lorsque la latence du réseau et le garbage collectionProcessus automatique de nettoyage de la mémoire vive utilisée par le serveur pour libérer de l'espace. de la JVMJava Virtual Machine : environnement d'exécution permettant de faire tourner les applications Java sur le serveur. faussent le timing d'exécution.

Pour éliminer ces bogues intermittents, nous devons disséquer les idées reçues architecturales qui surviennent lors de la gestion des contrôles de formulaire, des buffers de grille et des power subforms. Par exemple, placer une logique de validation dans Col Exited and Changed au lieu de Row Is Grid Buffer Row corrompt fréquemment le cache de la grille lorsque les utilisateurs saisissent rapidement. Aligner vos ER sur le cycle de vie précis du moteur web HTML — en gérant spécifiquement les threadsUnités d'exécution permettant au processeur de traiter plusieurs tâches de manière indépendante. BSFN asynchrones — garantit une exécution déterministe sans recourir à des boucles "sleep" fragiles.

Séquence de chargement du formulaire et pièges de l'initialisation du dialogue

Dans le Form Design Aid (FDA), placer des extractions de base de données ou des initialisations de variables dans l'événement 'Dialog is Initialized' est une erreur systémique qui casse régulièrement les applications personnalisées. À ce stade spécifique du cycle de vie du moteur d'exécution JAS, les valeurs Form Interconnect (FI)Structure de données permettant de transférer des paramètres entre deux écrans différents. transmises par l'application appelante ne sont souvent pas encore totalement liées aux structures internes du formulaire cible. J'ai récemment résolu un problème où un clone personnalisé de Sales Order Entry (P554210) générait des erreurs d'extraction intermittentes car le développeur tentait de sélectionner des enregistrements F0101Table centrale du carnet d'adresses (Address Book) contenant les informations des clients et fournisseurs. en utilisant un FI Address Number non lié durant cette phase précoce. Les valeurs existent dans la structure de données brute, mais les contrôles qui les mappent ne sont pas prêts.

Pour éviter ces échecs d'exécution, déplacez toutes les routines d'initialisation lourdes vers l'événement Post Dialog is Initialized. C'est l'emplacement correct car le serveur HTML a alors entièrement instancié les contrôles du formulaire, les structures de grille et les champs de filtre en mémoire. Exécuter vos E/S de tableEntrées/Sorties : opérations de lecture ou d'écriture directement dans les tables de la base de données. et vos affectations de variables ici garantit que le moteur d'exécution JDE peut mapper avec succès les paramètres entrants et alimenter en toute sécurité l'espace de travail du formulaire sans risquer de références de pointeurs nuls ou non initialisés.

Le déplacement de la logique lourde atténue également les goulots d'étranglement de performance sur la couche de présentation. Placer des appels de fonctions métier (BSFN) complexes — comme l'exécution du moteur CalculateSalesPricesAndCosts (B4500050) — à l'intérieur de 'Dialog is Initialized' bloque directement le thread de rendu du serveur HTML. Sur des connexions WANWide Area Network : réseau étendu reliant des sites distants, souvent sujet à des ralentissements. avec des latences supérieures à 80 ou 100 millisecondes, ce comportement de blocage synchrone déclenche souvent des erreurs HTTP 504 Gateway Timeout avant même que l'utilisateur ne voie la mise en page du formulaire sur son écran. Gardez cet événement précoce propre, en n'exécutant que des allocations de mémoire légères et non bloquantes.

Form Load and Grid Initialization Event Sequence

Erreurs de conception sur le chargement de la grille et la séquence Row Exit

Placer des extractions de base de données ou des BSFN synchrones à l'intérieur de l'événement Write Grid Line-Before est le moyen le plus rapide de transformer un chargement de grille standard en un goulot d'étranglement. Par exemple, lors du chargement de 200 à 500 lignes d'écritures comptables F0911Table principale du Grand Livre comptable stockant le détail de toutes les transactions financières., cet événement s'exécute des centaines de fois. Si vous appelez une BSFN lourde comme GetAuditInfo ou exécutez un JDB_Fetch personnalisé dans cet événement, le runtime FDA interrompt le rendu pour chaque enregistrement afin d'exécuter ce thread synchrone. Pour éviter cette latence, extrayez les données agrégées en amont dans l'événement Find Button Clicked ou déportez les détails secondaires vers une extraction asynchrone qui ne s'exécute que lorsqu'une ligne est explicitement sélectionnée.

Une erreur récurrente se produit lorsque les développeurs tentent de mettre à jour les valeurs de la grille de manière dynamique en modifiant les variables Grid Buffer (GB) à l'intérieur de l'événement Row Is Selected. Au moment où cet événement se déclenche, le moteur a déjà validé les données de la ligne dans le cache de la grille. Affecter une nouvelle valeur à une variable GBGrid Buffer : espace mémoire temporaire stockant les données d'une ligne de grille avant traitement. ici n'a aucun effet sur la ligne de grille active à l'écran ; le changement est simplement perdu en mémoire. Si vous devez mettre à jour la valeur d'une ligne en fonction de la sélection, vous devez explicitement utiliser la fonction système Update Grid Buffer suivie d'une affectation de variable GC ou forcer un rafraîchissement de cette ligne spécifique.

Se fier à l'événement Double Click on Row pour déclencher une logique de validation critique crée une faille massive de sécurité et d'intégrité des données. Les utilisateurs contournent fréquemment cet événement centré sur la souris en utilisant les touches Tab ou Entrée pour naviguer, ce qui déclenche l'événement Row Is Exited à la place. Si vos routines de validation, telles que la vérification des limites de crédit ou la sécurité par agence, n'existent que dans la logique du double-clic, les utilisateurs expérimentés utilisant le clavier enregistreront des données erronées directement dans vos tables. Déplacez ces validations vers Row Is Exited ou Row Is Exited and Changed - Inline pour garantir que le runtime les exécute quel que soit le mode de navigation dans la grille.

Écarts de timing entre Button Click et Post Button Click

Les développeurs compromettent régulièrement l'intégrité des applications car ils ne réalisent pas que l'événement 'Button Clicked' du bouton OK s'exécute de manière synchrone sur le serveur HTML, tandis que 'Post Button Clicked' s'exécute de manière asynchrone par défaut. Cette conception permet au formulaire interactif de se fermer immédiatement, déléguant les mises à jour lourdes de la base de données à un thread d'arrière-plan. L'inspection d'un jderoot.log lors d'une transaction standard P4210 Sales Order Entry révèle que le moteur HTML libère le thread de l'interface utilisateur alors que le Call Object KernelProcessus serveur JDE responsable de l'exécution de la logique métier (BSFN). traite encore le thread d'exécution BSFN asynchrone sur le serveur d'entreprise.

Cette scission architecturale provoque une condition de concurrence classique lorsque les développeurs placent des mises à jour de table dans 'Button Clicked' et des lectures subséquentes dans 'Post Button Clicked'. Dans la grande majorité des audits de performance d'applications personnalisées, généralement trois quarts ou plus, nous trouvons ce défaut de conception exact où un développeur tente de lire un enregistrement qui n'a pas encore été validé en base de données. L'opération de lecture dans le thread 'Post Button Clicked' s'exécute quelques millisecondes avant que l'écriture principale en base de données ne soit finalisée, entraînant une erreur intermittente SQL state 100Code d'erreur standard indiquant qu'une requête n'a trouvé aucun enregistrement correspondant dans la base de données. notoirement difficile à reproduire en développement local.

Les limites de traitement des transactions au niveau du formulaire sont complètement violées lorsque les développeurs mélangent des Master Business FunctionsBSFN complexes gérant l'intégrité totale d'une transaction métier (ex: création d'une commande). standard, comme F4211FSEndDoc s'exécutant sous contrôle de transaction dans 'Button Clicked', avec des insertions E/S de table personnalisées dans 'Post Button Clicked'. Si F4211FSEndDoc effectue un rollbackOpération d'annulation d'une transaction incomplète pour garantir que la base de données reste cohérente. sur le serveur d'entreprise en raison d'une violation de limite de crédit, votre insertion personnalisée dans 'Post Button Clicked' s'est déjà exécutée indépendamment hors de la limite de transaction, laissant des enregistrements orphelins dans vos tables personnalisées. Pour éviter cet échec d'intégrité des données, maintenez toutes les écritures interdépendantes dans l'événement 'Button Clicked' sous une seule limite de transaction, ou configurez les propriétés de l'événement 'Post Button Clicked' pour qu'il s'exécute de manière synchrone.

Synchronous vs Asynchronous BSFN Execution on OK Button

Validation des cellules de grille et Event Rules en cascade

Les développeurs déclenchent fréquemment des boucles infinies dans l'événement Col Exited and Changed Inline en tentant de formater ou de donner une valeur par défaut à une cellule au sein de la même colonne qui a déclenché l'événement. Écrire des Event Rules qui modifient GCGrid Column : variable représentant la valeur affichée dans une cellule spécifique de la grille. Address Number à l'intérieur de l'événement inline de GC Address Number marque à nouveau la cellule comme modifiée. Le moteur d'exécution détecte cette boucle récursive et l'interrompt de force, mais pas avant d'avoir consommé des cycles CPUProcesseur : composant matériel qui exécute les instructions des programmes informatiques. et laissé la ligne de grille dans un état instable et partiellement calculé. La manipulation de champs auto-référencés doit être protégée par un contrôle de comparaison strict.

Le déplacement des calculs vers l'événement Col Exited and Changed Async introduit un ordre d'exécution non déterministe. Comme l'événement Async s'exécute sur un thread d'arrière-plan sur le serveur HTML, les calculs ultérieurs au niveau de la ligne ne peuvent pas se fier à son ordre d'exécution. Si un développeur affecte un taux de taxe dans l'événement Async de la colonne agence, et calcule immédiatement le prix étendu dans l'événement Inline de la colonne suivante, le calcul utilisera par intermittence un taux de taxe vide ou obsolète. Cette condition de concurrence provoque des erreurs de décimales mathématiques intermittentes dans des applications comme Sales Order Entry (P4210).

Les erreurs de validation définies via 'Set Action Code Error' dans les événements au niveau de la cellule n'arrêtent pas automatiquement l'exécution du traitement du bouton OK au niveau du formulaire, sauf si elles sont explicitement vérifiées dans l'événement 'Button Clicked'. Le runtime affiche l'erreur rouge sur la cellule de la grille, mais cliquer sur OK contourne ce blocage à moins que vous n'interrogiez explicitement l'état d'erreur du système. Les développeurs doivent utiliser la fonction système Was Is-Error Occurred dans l'événement 'Button Clicked' du bouton OK pour interrompre le traitement avant que les données ne soient validées via des fonctions métier comme B4200310.

Synchronisation des événements Parent-Enfant dans les Power Forms

Les développeurs qui construisent des écrans multi-grilles complexes — comme une version personnalisée de P42101 — supposent fréquemment que la Power FormType d'écran avancé permettant d'afficher et de lier plusieurs sous-formulaires sur une seule page. parente et ses sous-formulaires enfants s'initialisent de manière synchrone. Ce n'est pas le cas. L'événement 'Post Dialog is Initialized' de la Power Form parente s'exécute et se termine avant même que le 'Dialog is Initialized' du sous-formulaire enfant ne commence. Cet écart d'initialisation surprend les développeurs lorsqu'ils tentent de transmettre des critères de filtrage au sous-formulaire pendant la séquence de démarrage du parent. Les valeurs de la structure de données disparaissent car l'espace de travail du sous-formulaire cible n'existe pas encore dans la pile d'appels.

Pour combler cet écart en toute sécurité, vous devez utiliser les paramètres d'événement Notifying Child et Notifying Parent. Un échec courant se produit lorsqu'un développeur contourne ces paramètres, tentant d'écrire directement dans la structure de mapping du sous-formulaire à partir d'un événement parent avant que le contexte d'exécution de l'enfant ne soit établi. Dans le moteur client HTML, ce mapping prématuré déclenche des NullPointerExceptionsErreur informatique survenant lorsqu'un programme tente d'utiliser une référence mémoire qui n'existe pas. silencieuses ou laisse des variables non initialisées, entraînant des grilles vides. La règle est absolue : ne poussez jamais de données vers un sous-formulaire tant que l'événement 'Notifying Child' n'a pas explicitement été déclenché pour signaler que la structure de données de l'enfant est prête à recevoir des entrées.

Des goulots d'étranglement de performance apparaissent lorsque les développeurs déclenchent la fonction système 'Update Parent' depuis l'événement 'Grid Record is Fetched' d'un sous-formulaire lors de chargements massifs de centaines de lignes. Chaque exécution de 'Update Parent' force le serveur HTML à sérialiser l'état complet du sous-formulaire vers le conteneur parent. Faire cela à l'intérieur d'un événement de grille à haute fréquence sature rapidement le heap JVMZone de mémoire vive allouée au serveur Java pour stocker les objets et données actives. de votre serveur HTML WebLogicServeur d'applications Oracle utilisé pour héberger et faire fonctionner l'interface web de JD Edwards., faisant grimper les temps de garbage collection et provoquant des déconnexions de session intermittentes pour les utilisateurs concurrents. Au lieu de cela, bufferisez vos calculs de grille localement dans le sous-formulaire et ne déclenchez un événement de synchronisation unique que lorsque l'utilisateur enregistre explicitement.

Risques liés aux threads des fonctions métier asynchrones

Cocher la case d'exécution Asynch dans le Form Design Aid (FDA) pour des Master Business Functions (MBF) comme F4211FSBeginDoc est une erreur d'optimisation fréquente qui casse la gestion standard des erreurs. Lorsque vous exécutez ces moteurs de validation complexes de manière asynchrone, le thread de l'application interactive passe la main et passe immédiatement à la ligne suivante des Event Rules. Le runtime ne peut pas mapper les messages d'erreur résultants vers les contrôles du formulaire, ce qui signifie que les utilisateurs ne voient jamais les blocages critiques de limite de crédit ou les échecs de conversion d'unité de mesure, ce qui conduit à des abandons de transaction silencieux.

Cette déconnexion asynchrone provoque de graves corruptions de données lorsque les utilisateurs cliquent rapidement à travers les écrans. Si une APPL initie un thread BSFN asynchrone pour F4311FSEndDoc sur le bouton "OK" et que l'utilisateur ferme immédiatement le formulaire ou change de page, le serveur HTML termine souvent le thread sous-jacent prématurément. Dans les flux d'achats, cette troncature crée régulièrement des enregistrements d'en-tête F4301 orphelins avec des enregistrements de détail F4311 manquants, nécessitant une intervention directe en base de données SQL pour purger les lignes corrompues.

Pour garantir l'intégrité des données, vous devez définir des limites de traitement de transaction explicites dans la boîte de dialogue Form Properties. Lorsque des BSFN personnalisées s'exécutant dans l'événement Post Button Clicked doivent participer à la même unité de validation en base de données que les insertions de grille standard, le traitement des transactions doit être activé au niveau du formulaire. Vous devez ensuite cocher manuellement l'option "Transaction Processing" sur chaque appel BSFN individuel. Cela garantit que si l'écriture du détail F4311 échoue, l'ensemble de la transaction métier effectue un rollback propre plutôt que de laisser des mises à jour partielles et inexploitables dans la base de données.