IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Voir le flux RSS

Fran�ois DORIN

[Actualit�] Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C#

Note : 2 votes pour une moyenne de 3,00.
par , 08/04/2018 � 23h18 (6208 Affichages)
Bonjour,

Dans le billet du jour, nous allons avoir comment nous pouvons int�grer une classe, �crite initialement en Java, directement en C#, � travers un exemple concret : g�n�rer un PDF � partir de la biblioth�que Apache FOP.

Cela ne serait pas possible aussi facilement sans le projet IKVM.NET, qui est une impl�mentation de Java pour environnement .Net (Mono et le framework .NET de Microsoft).

Ce billet �tant ax� sur l'interop�rabilit� entre Java/.NET, je ne m'attarderai pas sur l'usage de Apache FOP.

Principe
Le principe retenu ici est assez simple.

Dans un premier temps, on va convertir le fichier .jar de la biblioth�que Apache FOP en un assembly .NET. Pour ce faire, on va utiliser l'utilitaire ikvmc qui permet de convertir le bytecode Java en assembly .NET.

Dans un second temps, on va utiliser cet assembly au sein d'un programme C#.

Pr�paration
Avant de proc�der � la g�n�ration de l'assembly,il nous faut r�cup�rer l'ensemble des outils n�cessaires via leur site respectif :


Une fois les outils t�l�charg�s, il faudra les extraire dans le dossier de votre choix.

Conversion .jar vers .dll
Ici, pas grand chose � faire. Si ce n'est ex�cuter le petit script suivant (avec quelques modifications en fonction de votre installation) :
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
SET IKVM_BIN_PATH=C:\Users\fdori\Downloads\ikvmbin-7.2.4630.5\ikvm-7.2.4630.5\bin
set PATH=%PATH%;%IKVM_BIN_PATH%

ikvmc -target:library *.jar ../build/fop.jar -out:fop.dll
La premi�re partie du script permet d'indiquer o� se trouve le binaire de IKVM que vous avez t�l�charg� � l'�tape pr�c�dente. Au passage, on peut voir que pour ma part, j'utilise la version 7.2.4630.5.

La derni�re ligne du script est celle qui proc�de effectivement � la conversion .jar -> .dll. Elle doit �tre ex�cut� dans le sous-r�pertoire fop/lib de l'archive contenant Apache FOP.

Les param�tres pass�s sont les suivants (voir doc officielle pour plus d'informations) :
  • -target: library : on indique ici que l'on souhaite g�n�r� un assembly .dll. Les autes cibles possibles sont "exe" pour une application console et "winexe" pour une application graphique ;
  • *.jar : on indique ici les fichiers � inclure. Pour des raisons de simplicit�, et dans la mesure o� Apache FOP vient avec l'ensemble de ses d�pendances, on utilise le caract�re g�n�rique * ;
  • out:fop.dll : nom du fichier de sortie, c'est-�-dire ici de l'assembly qui sera g�n�r�.


Mise en oeuvre
Maintenant que nous disposons de l'assembly fop.dll, nous pouvons l'utiliser dans un projet C# (ou VB.NET) classique. Il suffit d'ajouter � notre projet la r�f�rence de l'assembly que nous venons de g�n�rer.
Vous aurez aussi besoin de r�f�rencer des assemblys du projet IVMK. Pour Apache FOP, j'ai �u r�f�rencer les assemblys suivants :
  • IKVM.OpenJDK.Core ;
  • IKVM.OpenJDK.XML.API ;
  • IKVM.OpenJDK.XML.Transporm.


Le premier sera n�cessaire dans tous les cas, car il contient les routines de bases de l'API Java.

Et maintenant le code :

Code C# : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
     public static void GenererPDF(System.Xml.XmlDocument source, string sourceToFOPXsltFileName, string ouputFileName)
        {
            // Récupération du fichier XSL
            System.Xml.Xsl.XslCompiledTransform xslt = new System.Xml.Xsl.XslCompiledTransform();
            xslt.Load(sourceToFOPXsltFileName);
 
            // Génération du fichier FOP
            string foFileName = System.IO.Path.GetTempFileName();
            using (System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(foFileName, System.Text.Encoding.UTF8))
            {
                xslt.Transform(source.CreateNavigator(), null, writer);
                writer.Close();
            }
 
            // Création du PDF par interop IKVM avec ApacheFOP
            java.io.File fo = new java.io.File(foFileName);
            java.io.File pdf = new java.io.File(ouputFileName);
            org.apache.fop.apps.FopFactory fopFactory = GetFactory();
            org.apache.fop.apps.FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
            java.io.OutputStream sortie = new java.io.BufferedOutputStream(new java.io.FileOutputStream(pdf));
            org.apache.fop.apps.Fop fop = fopFactory.newFop("application/pdf", foUserAgent, sortie);
            javax.xml.transform.TransformerFactory factory = javax.xml.transform.TransformerFactory.newInstance();
            javax.xml.transform.Transformer transformer = factory.newTransformer();
            javax.xml.transform.Source src = new javax.xml.transform.stream.StreamSource(fo);
            javax.xml.transform.Result res = new javax.xml.transform.sax.SAXResult(fop.getDefaultHandler());
            transformer.transform(src, res);
            sortie.close();
        }      
 
        public static FopFactory GetFactory()
        {
            ResourceResolver myResolver = new MyResolver();
            File file = new File(fop_dir);
            FopFactoryBuilder builder = new FopFactoryBuilder(file.toURI(), myResolver);
            FontManager fontManager = builder.getFontManager();
 
            return builder.build();
        }
Code C# : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
    public class MyResolver : ResourceResolver
    {
        public OutputStream getOutputStream(URI uri)
        {
            return null;
        }
 
        /// <summary>
        /// Méthode appelée pour récupérer des ressources externes, comme les images
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public Resource getResource(URI uri)
        {
            return null;
        }
    }
La classe MyResolver est une impl�mentation tr�s basique et am�liorable que n�cessite Apache FOP pour r�cup�rer les ressources externes.

Conclusion
Comme on peut le constater, l'utilisation de IKVM est assez simple et permet d'utiliser une biblioth�que Java en C# avec un minimum d'effort. Cette approche n'est pas encore parfaite et peut parfois rencontrer quelques bugs, mais le fait qu'un projet de la taille d'Apache FOP soit support� est quand m�me tr�s encourageant.

Il peut tout � fait �tre utilis� pour g�rer une partie non critique d'une application (comme la g�n�ration de PDF, comme dans cet exemple).

Il existe �galement d'autres m�thodes pour interfacer du code Java et .NET. L'approche de IKVM est int�ressante dans la mesure o� elle se base sur une conversion du bytecode Java en assembly. Autrement dit, il n'est pas n�cessaire d'avoir une JVM d'installer pour pouvoir utiliser le code converti !

Envoyer le billet � Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C# � dans le blog Viadeo Envoyer le billet � Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C# � dans le blog Twitter Envoyer le billet � Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C# � dans le blog Google Envoyer le billet � Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C# � dans le blog Facebook Envoyer le billet � Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C# � dans le blog Digg Envoyer le billet � Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C# � dans le blog Delicious Envoyer le billet � Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C# � dans le blog MySpace Envoyer le billet � Interop�rabilit� Java/.NET avec IKVM : utiliser du code �crit en Java depuis un code C# � dans le blog Yahoo

Cat�gories
Java , DotNET , C#

Commentaires

  1. Avatar de Mickael Baron
    • |
    • permalink
    Bonjour Fran�ois,

    Il manque une information importante est la version Java que IKVM peut supporter. Si j'ai une biblioth�que �crite en Java 9 est-ce que �a peut fonctionner ?

    Merci pour le billet (diffus� sur la rubrique Java ;-))

    Mickael
  2. Avatar de Fran�ois DORIN
    • |
    • permalink
    J'attends le billet dans l'autre sens : utiliser IKVM pour g�nerer les stub n�cessaire pour appeler du code .NET en Java

    Pour les versions de Java support�es, je ne trouve pas vraiment d'information. Maintenant, comme IKVM travaille directement sur le bytecode, je suppose que :
    • tant que la JVM elle-m�me n'est pas modifi�e (pour inclure de nouvelles op�rations par exemple), il n'y a pas de soucis ;
    • tant que les API utilis�es sont support�es, il ne devrait pas y avoir de soucis (et c'est le cas des API de base) ;
    • tant qu'il n'y a pas d'appels natifs (JNI & co.).


    Je pense que le meilleur moyen de savoir si �a marche, c'est de tester !
  3. Avatar de jlliagre
    • |
    • permalink
    La derni�re version sur laquelle le d�veloppeur d'IKVM a travaill� semble �tre OpenJDK 8u45, mais il a abandonn� le projet depuis ...

    The End of IKVM.NET
    After almost fifteen years I have decided to quit working on IKVM.NET. The decision has been a long time coming. Those of you that saw yesterday�s Twitter spat, please don�t assume that was the cause. It rather shared an underlying cause. I�ve slowly been losing faith in .NET. Looking back, I guess this process started with the release of .NET 3.5. On the Java side things don�t look much better. The Java 9 module system reminds me too much of the generics erasure debacle.
    Source: http://weblog.ikvm.net/
  4. Avatar de tomlev
    • |
    • permalink
    �a a l'air sympa IKVM... dommage que ce soit abandonn� :S
    http://weblog.ikvm.net/2017/04/21/TheEndOfIKVMNET.aspx
  5. Avatar de Fran�ois DORIN
    • |
    • permalink
    Mais mais mais... comment j'ai fait pour ne pas tomber sur le blog et ne pas voir que le projet �tait abandon� ?

    Je trouve dommage que cela n'apparaisse pas sur le site. C'est une info utile pourtant ! Merci � vous pour avoir soulev� ce "d�tail".