* Bonjour, *
Est-il possible depuis un package d'appeler une fonction statique Java, fonction statique qui elle-même appelle une fonction native C ?
* Merci *
* Bonjour, *
Est-il possible depuis un package d'appeler une fonction statique Java, fonction statique qui elle-même appelle une fonction native C ?
* Merci *
Oui via les procédures externes.
Les appels Java standards semblent être supportés mais pas les appels de type JNI (Java Native Invocation).
![]()
Et les Java Native Invocation ne sont pas en gros, des appels depuis Java du code écrit en C ou autre ?
C'est quoi votre problème en fait ?
JNI = appels Java vers librairie C.
A priori, la JVM Oracle ne supporte pas cette fonctionnalité.
Les appels Java standards ne posent pas de problèmes.
Sur certains forums, certaines personnes semblent dire que les appels JNI pourraient marcher mais qu'Oracle ne les supportait pas officiellement.
Voici le lien :
http://download.oracle.com/docs/cd/E...e.htm#CACFCDJF
J'ai essayé de passer outre ce "non support officiel" mais sans succès. Je n'ai pas réussi à appeler ma librairie C depuis un appel JNI en PL/SQL, alors que je n'ai pas de problème pour faire des appels Java standards. D'où mes questions :Oracle Database does not support the use of JNI in Java applications. If you use JNI, then your application is not 100 percent pure Java and the native methods require porting between platforms. Native methods can cause server failure, violate security, and corrupt data.
- est-ce quelqu'un a déjà fait cela ?
- Y-a-t'il un tutoriel qui marche (j'en ai essayé plusieurs sur le NET. Aucun ne fonctionne) ?
Pour info, je suis soit sous Oracle 9i, soit sous Oracle 10g.
Bref, j'avais pensé qu’au lieu d’appeler à partir du PL/SQL du Java qui appelle du C vous pourriez appeler directement le C à partir du PL/SQL.
Oui, c'est d'ailleurs ce que l'on fait actuellement.
Le problème est que Oracle gère très mal cela : les appels directs vers C (au travers d'une librairie C) sont re-routés vers un process extproc qui les prends alors en charge.
Oracle lance 1 process extproc par session --> cela devient très vite très gourmand en ressources.
Si une session crashe brutalement, le process extproc n'est pas tué !
De plus, il est impossible de relancer le listener tant qu'il existe au moins 1 process extproc qui tourne.
Le serveur peut donc être très vite saturé en ressources.
La gestion des appels C n'est donc pas très robuste. Et il me semble d'ailleurs qu'Oracle désencourage l'utilisation des appels C.
Les appels JAVA par contre ne sont pas re-routés via le process extproc.
Oui, ça marche comme ça pour le C
- passage par le processus extproc
- un extproc par session
- durée jusqu'à la deconnexion de la session.
Que fait votre code C ? Doit-il envoyé au programme appelant des résultats (il implémente un algorithme) ou il peut s'exécuter d'une manière indépendante (il exécute une tâche, etc) ?
En fait, la librairie C permet d'envoyer des messages (traces, logs, alarmes, ...) à un service en charge de les collecter, archiver et rerouter éventuellement.
La librairie C ouvre donc un canal de communication entre le process appelant (ici Oracle mais des wrappers vers cette librairie ont été développés pour être appelés depuis des applications en C#, PowerBuilder, Java, Scripts shell, ...) et le service de collecte.
Le canal de communication est du type "shared memory" (mappage d'un fichier en mémoire) synchronisée par des sémaphores. On aurait pu utiliser des sockets mais le mécanisme de "shared memory" est beaucoup plus rapide et moins gourmand que les sockets.
Ce service (unique) de collecte permet de collecter de manière séquentielle (et donc en respectant l'historique) de toutes les traces / logs d'une même plate-forme. Cela est très utile lorsqu'une application est multi-process et multi-langages. C'est le cas ici où notre application fait appel à Oracle, des programmes en C, en C# et en PowerBuilder qui dialoguent entre eux.
Si je comprends bien votre code PL/SQL devrait toute simplement appeler la librairie C sans avoir besoin d'un retour.
Dans ce cas pour la version 10g il y la possibilité d'exécuter un programme externe via DBMS_SCHEDULER.
Le package DBMS_SCHEDULER permet uniquement d'appeler d'autres packages ou procédures PL/SQL.
Il reste que pour s'interfacer avec notre API en C, on est obligé de passer par la méthode extproc, Oracle ne supportant pas les appels JNI depuis Java.
J'ai bien l'impression qu'il n'y a pas d'issue possible autre que extproc avec tous les problèmes qu'il sous-entend.
1) Lisez le chapitre 28 External procedures. Il semblerait qu'il est possible de configurer le processus extproc en mode multithreading.
2) Dbms_Scheduler peut exécuter des programmes externes
program_type
This attribute specifies the type of program you are creating. If it is not specified then you will get an error. There are three supported values for program_type:
•'PLSQL_BLOCK'
This specifies that the program is a PL/SQL block. Job or program arguments are not supported when the job or program type is PLSQL_BLOCK. In this case, the number of arguments must be 0.
•'STORED_PROCEDURE'
This specifies that the program is a PL/SQL or Java stored procedure, or an external C subprogram. Only procedures, not functions with return values, are supported. PL/SQL procedures with INOUT or OUT arguments are not supported.
•'EXECUTABLE'
This specifies that the program is external to the database. External programs implies anything that can be executed from the operating system's command line. AnyData arguments are not supported with job or program type EXECUTABLE.
Partager