IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

JNI, comment ça marche ?


Sujet :

Entrée/Sortie Java

  1. #1
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut JNI, comment ça marche ?
    Bonjour,

    j'ai quelques soucis dans l'utilisation de JNI, et les tutos que j'ai pu trouver pour l'instant ne m'ont pas paru très clairs.

    Je fais le portage de bibliothèques écrites pour Linux, intégrées à Eclipse sous forme d'un plugin.

    Je génère sans problème mes dll.
    J'arrive à les charger (avec System.load), mais dès que j'essaye d'appeler une fonction de ma dll, tout foire.

    Code : 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
    !ENTRY org.eclipse.osgi 4 0 2011-05-18 11:08:28.867
    !MESSAGE An error occurred while automatically activating bundle OTAWA (759).
    !STACK 0
    org.osgi.framework.BundleException: Exception in adtree.ADTREEPlugin.start() of bundle OTAWA.
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:806)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:755)
    [.......]
    	at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
    	at org.eclipse.equinox.launcher.Main.main(Main.java:1384)
    Caused by: java.lang.UnsatisfiedLinkError: ojawa.Otawa.idLABEL()J
    	at ojawa.Otawa.idLABEL(Native Method)
    	at ojawa.Otawa.<clinit>(Otawa.java:37)
    	at adtree.ADTREEPlugin.start(ADTREEPlugin.java:234)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:783)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:774)
    	... 74 more
    Root exception:
    java.lang.UnsatisfiedLinkError: ojawa.Otawa.idLABEL()J
    	at ojawa.Otawa.idLABEL(Native Method)
    	at ojawa.Otawa.<clinit>(Otawa.java:37)
    	at adtree.ADTREEPlugin.start(ADTREEPlugin.java:234)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:783)
    [.......]
    	at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
    	at org.eclipse.equinox.launcher.Main.main(Main.java:1384)
    Par exemple sur le code java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String info = "OJAWA V" + ojawa.Otawa.version() + " (" + ojawa.Otawa.date() + ") found";
    déclaré ainsi dans ojawa.Otawa (public abstract Class):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static native String version();
    Pourquoi ?

  2. #2
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Par défaut
    bonjour,

    As tu correctement nommé les méthodes dans ta lib ?
    Car avec JNI les méthodes sont nommées de la façon suivant :
    Java_<nom de la classe (avec package s'il y en a) >_<nom de la methode>

    Si tu ne respecte pas cette règle alors tu t'exposes a une exception java.lang.UnsatisfiedLinkError, ce qui semble être ton cas !
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut
    Elle est déclarée comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /*
     * Class:     ojawa_Otawa
     * Method:    version
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_ojawa_Otawa_version
    (JNIEnv *env, jclass clazz) {
    	return env->NewStringUTF(VERSION);
    }
    Au passage, tout fonctionne très bien sous Linux (mais en invoquant des .so et pas des .dll).

  4. #4
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Par défaut
    d'après le message d'erreur ce n'est pas la méthode "version" qui pose problème mais "ojawa.Otawa.idLABEL()" !
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut
    Elle est déclarée comme suit, mais au debogage, ça plante sur la ligne appelant version et date (en redécoupant la construction du String, ça coupe sur les deux, et pas juste un des deux).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /*
     * Class:     ojawa_Otawa
     * Method:    idLABEL
     * Signature: ()J
     */
    JNIEXPORT jlong JNICALL Java_ojawa_Otawa_idLABEL(
    	JNIEnv *env,
    	jclass clazz)
    {
    	return (jlong)&LABEL;
    }

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Citation Envoyé par ManusDei Voir le message
    mais au debogage, ça plante sur la ligne appelant version et date (en redécoupant la construction du String, ça coupe sur les deux, et pas juste un des deux).
    Non, le stacktrace mentionne bien que l'erreur a lieu sur l'initialisation statique de la classe, qui a lieu de manière automatique à la première utilisation de la classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	at ojawa.Otawa.idLABEL(Native Method)
    	at ojawa.Otawa.<clinit>(Otawa.java:37)
    Bref, regardez sur coté de Otawa.java:37

  7. #7
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut
    J'ai une autre question, peut-être liée. J'ai lu dans quelques tuto des références à un fichier .def, c'est quoi ?
    Est-ce que c'est nécessaire, et spécifique à windows (et donc expliquerais pourquoi tout fonctionne sous linux et pas sous windows) ?

    Otawa.java : 37 ressemble à ceci (ligne 4)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	public static native long idLABEL();
     
    	public static final Identifier LABEL =
    		Identifier.get(idLABEL());
    La fonction get à ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	static Identifier get(long ptr) {
    		return cache.get(ptr);
    	}
    et cache.get à ceci

    Code : 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
     
    private final Hashtable<Long, SoftReference<T> > tab =
    	new Hashtable<Long, SoftReference<T> >();
     
    public T get(long ptr) {
    	if(ptr == 0)
    		return null;
    	T res;
    	SoftReference<T> ref = tab.get(ptr);
    	if(ref == null) {
    		res = make(ptr);
    		tab.put(ptr, new SoftReference<T>(res));
    	}
    	else {
    		res = ref.get();
    		if(res == null) {
    			res = make(ptr);
    			tab.put(ptr, new SoftReference<T>(res));				
    		}
    	}
    	return res;
    }
    Bref le code Java semble bon, et le problème semble bien venir de l'appel native.

    Question subsidiaire, c'est le <clinint> qui fait dire que c'est à l'initialisation statique de la classe ?

  8. #8
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Citation Envoyé par ManusDei Voir le message
    Otawa.java : 37 ressemble à ceci (ligne 4)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	public static native long idLABEL();
     
    	public static final Identifier LABEL =
    		Identifier.get(idLABEL());
    Je pense bien que vous appelez donc votre idLABEL() avant de faire votre System.load....

  9. #9
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut
    Je suis à peu près sûr que non, le load est ligne 3 et la String construite ligne 9.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try {
    	if(os.startsWith("Windows")){
    		System.load(path); // le load
    		logInfo("using relocated OJAWA from " + path); // j'ai bien le (bon) chemin vers la dll qui s'affiche
    }
    catch(java.lang.UnsatisfiedLinkError e) {
    //des choses inutiles, vu qu'on y passe pas
    }
    String info = "OJAWA V" + ojawa.Otawa.version() + " (" + ojawa.Otawa.date() + ") found"; // et là ça plante
    logInfo(info);
    J'ai vérifié dans mon CMakeFile, le fichier cpp est est bien inclus pour la dll.

    Par contre, à la place des fenêtres que je devrais avoir dans Eclipse, j'ai (le message pour une des fenêtres):

    Could not create the view: Plug-in OTAWA was unable to load class adtree.views.log.LogView.

    Code : 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
    org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter$TerminatingClassNotFoundException: An error occurred while automatically activating bundle OTAWA (759).
    	at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:121)
    	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:453)
    	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:393)
    	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:469)
    	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)
    	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)
    	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    	at java.lang.ClassLoader.loadClass(Unknown Source)
    	at org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:338)
    [......]
    	at org.eclipse.equinox.launcher.Main.main(Main.java:1384)
    Caused by: org.osgi.framework.BundleException: Exception in adtree.ADTREEPlugin.start() of bundle OTAWA.
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:806)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:755)
    	at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:370)
    	at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:284)
    	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:417)
    	at org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:265)
    	at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:106)
    	... 56 more
    Caused by: java.lang.UnsatisfiedLinkError: ojawa.Otawa.idLABEL()J
    	at ojawa.Otawa.idLABEL(Native Method)
    	at ojawa.Otawa.<clinit>(Otawa.java:37)
    	at adtree.ADTREEPlugin.start(ADTREEPlugin.java:234)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:783)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:774)
    	... 62 more
    Pas la même exception, mais ça vient de idLABEL() également.

  10. #10
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    on peux voir la classe complète?

  11. #11
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Par défaut
    ce bout de code ne donne rien puisque ce n'est pas la ligne 9 qui plante mais belle et bien la ligne 37 de la classe Otawa !

    sans le contexte complet difficile d'en dire plus !
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut
    Les classes sont en dessous, mais connaissez-vous des tutos suffisamment exhaustifs sur JNI ? J'ai du mal à en trouver qui présentent autre chose qu'un cas "basique".

    Classe ADTREEPLugin.java, avec le chargement de dll ligne 224, construction de la String ligne 235

    Code : 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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
     
    /*
     * $Id$
     * 
     * 
     * This library is free software; you can redistribute it and/or
     * modify it under the terms of the GNU Lesser General Public
     * License as published by the Free Software Foundation; either
     * version 2.1 of the License, or (at your option) any later version.
     *
     * This library is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     * Lesser General Public License for more details.
     * 
     * You should have received a copy of the GNU Lesser General Public
     * License along with this library; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     */
    package adtree;
     
    import ojawa.WorkSpace;
     
    import org.eclipse.core.resources.*;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.graphics.Color;
    import org.eclipse.swt.graphics.Image;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.ui.plugin.*;
    import org.eclipse.jface.dialogs.ErrorDialog;
    import org.eclipse.jface.preference.IPreferenceStore;
    import org.eclipse.jface.preference.PreferenceConverter;
    import org.eclipse.jface.resource.ImageDescriptor;
    import org.eclipse.jface.resource.ImageRegistry;
    import org.osgi.framework.BundleContext;
    import java.util.*;
    import java.io.*;
    import java.net.*;
     
    import javax.swing.event.EventListenerList;
     
    import org.eclipse.ui.*;
    import org.eclipse.core.runtime.*;
     
    import adtree.controler.ADTREEControler;
    import adtree.scripts.ScriptManager;
     
     
    /**
     * The main plugin class to be used in the desktop.
     */
    public class ADTREEPlugin extends AbstractUIPlugin {
    	private ImageRegistry image_registry = new ImageRegistry();
     
    	// part identifier
    	public static final String CFG_EDITOR_ID = "adtree.editor.jung.CFGEditorPart";
     
    	// constants
    	public static final String	PLUGIN_TAG = "ADTREE",
    								RECENTS_TAG = "recents",
    								RECENT_TAG = "recent",
    								WCET_TAG = "wcet";
     
    	// element identifiers
    	public static final String	CLASS_COLOR_TAG = "class-color",
    								CLASS_NUM_TAG = "class-num",
    								FF_TAG = "ff",
    								FFC_TAG = "ffct",
    								FLOWFACT_TAG = "flowfact",
    								FLOWFACTS_TAG = "flowfacts",
    								LOOP_TAG = "loop",
    								NOTE_TAG = "note",
    								PROGRAM_TAG = "program",
    								TASK_TAG = "task";
     
    	// attribute identifiers
    	public static final String	ADDR_ATT = "addr",
    						BLUE_ATT = "blue",
    						BRANCH_ATT = "branch",
    						CHECKSUM_ATT = "checksum",
    						CONF_SCRIPT_ATT = "configuration",
    						CONTROL_ATT = "control",
    						EXACT_ATT = "exact",
    						EXEC_ATT = "executed",
    						EXTERN_ATT = "extern",
    						FILE_ATT = "file",
    						GREEN_ATT = "green",
    						KIND_ATT = "kind",
    						LABEL_ATT = "label",
    						LIMIT_ATT = "limit",
    						LINE_ATT = "line",
    						LOOPID_ATT = "loopid",
    						MAX_ATT = "max",
    						MAXEXPR_ATT = "maxexpr",
    						MIN_ATT = "min",
    						NAME_ATTR = "name",
    						NUMCALL_ATT = "numcall",
    						OFFSET_ATT = "offset",
    						OPTION_ATT = "option",
    						PATH_SCRIPT_ATT = "path_script",
    						PROJECT_ATT = "project",
    						RED_ATT = "red",
    						SOURCE_ATT = "source",
    						TOTAL_ATT = "total",
    						TOTEXPR_ATT = "totalexpr",
    						TSKN_ATT = "taskname",
    						UNRESOLVED_ATT = "unresolved",
    						WCET_ATT = "wcet";
     
    	// flow fact kinds
    	public static final String	FUNCTION_KIND = "function",
    								CALL_KIND = "call",
    								NO_CALL_KIND = "no_call";
     
    	public static final String OTAWA_FILE = "otawa.xml";
    	public static final Event PROP_REFRESH_EVENT = new PropRefreshEvent();
     
    	// the shared instance.
    	private static ADTREEPlugin plugin;
    	private static final int RECENT_CAPACITY = 5;
    	private final LinkedList<String> recent_files = new LinkedList<String>();
    	private static ScriptManager scripts = new ScriptManager();
     
    	// colorization
    	public static final ADTREEControler controler =new ADTREEControler();
     
    	//The identifiers for the preferences	
    	public static final String BAD_WORDS_PREFERENCE = "badwords";
    	public static final String HIGHLIGHT_PREFERENCE = "highlight";
     
    	//The default values for the preferences
    	public static final String DEFAULT_BAD_WORDS = "bug;bogus;hack;";
    	public static final int DEFAULT_HIGHLIGHT = SWT.COLOR_BLUE;
     
    	// configuration
    	public boolean 	display_unnamed = false,
    					display_unlabeled = true;
     
    	// data
    	private EventListenerList listeners = new EventListenerList();
    	private LinkedList<Prog> progs = new LinkedList<Prog>();
    	boolean colorize = false;
    	Task colorized_task = null;
     
    	/**
             * The constructor.
             */
    	public ADTREEPlugin() {
    		plugin = this;
    	}
     
    	/**
             * Get the script manager.
             * @return              Script manager.
             */
    	public final ScriptManager getScripts() {
    		return scripts;
    	}
     
    	/**
             * Get the image registry.
             * @return      Image registry.
             */
    	public final ImageRegistry getImageRegistry() {
    		return image_registry;
    	}
     
    	/**
             * Declare the image from the given list of pair (image key, image path).
             * @param images        Images to declare.
             */
    	public final void declareImages(String[] images) {
    		String iconPath = "/icons/";
    		for(int i = 0; i < images.length - 1; i += 2)
    			if(image_registry.get(images[i]) == null)
    				image_registry.put(
    					images[i],
    					ImageDescriptor.createFromFile(adtree.views.property.ViewProperty.class, iconPath + images[i + 1])
    				);			
    	}
     
    	/**
             * Get an image from its key.
             * @param key   Image key.
             * @return              Image or null if none.
             */
    	public Image getImage(String key) {
    		return image_registry.get(key);
    	}
     
    	/**
             * This method is called upon plug-in activation
             */
    	public void start(BundleContext context) throws Exception {
    		super.start(context);
     
    		// build OJAWA path
    		String dirpath = null;
    		String path = FileLocator.toFileURL(FileLocator.find(context.getBundle(), new Path("/"), null)).getPath();
    		String os = java.lang.System.getProperty("os.name");
    		if(os.equals("Linux"))
    			path = path + "/libotawa/lib/libojawa.so";
    		else if(os.startsWith("Windows")){
    			path = FileLocator.getBundleFile(context.getBundle()).getAbsolutePath();
    			dirpath = path + "\\libotawa\\lib\\";
    			path = path + "\\libotawa\\lib\\libojawa.dll";
    			//if(new File(path).exists())
    			//	path = "found "+path;
    		}
    		else {
    			path = null;
    			ADTREEPlugin.logError("unsupported OS: OTAWA library shouldn't be accessible.", null);
    		}
     
    		// link with OJAWA
    		try {
    			if(os.startsWith("Windows")){
    				System.load(dirpath+"libxml2.dll");
    				System.load(dirpath+"iconv.dll");
    				System.load(dirpath+"zlib1.dll");
    				System.load(dirpath+"libexslt.dll");
    				System.load(dirpath+"libxslt.dll");
    			}
    				System.load(path);
    				logInfo("using relocated OJAWA from " + path);
    		}
    		catch(java.lang.UnsatisfiedLinkError e) {
    			logInfo("can not find relocated OJAWA at " + path + ": attempting from libraries of LD_LIBRARY_PATH.");
    			e.printStackTrace();
    			if(os.equals("Linux"))
    				System.loadLibrary("ojawa");
    			else if(os.startsWith("Windows"))
    				System.loadLibrary("libojawa");
    		}
    		String info = "OJAWA V" + ojawa.Otawa.version() + " (" + ojawa.Otawa.date() + ") found";
    		logInfo(info);
     
    		// configure Swing UI
    		/* !!WARNING!! With last version of JVM (1.6), seems to cause CDT freeze ?!?
    		try {
    			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    		 } catch (Exception exc2) {
    			    System.err.println("Could not load LookAndFeel: ");
    		 }*/
     
    		// load configuration
    		loadConf();
    	}
     
    	/**
             * This method is called when the plug-in is stopped
             */
    	public void stop(BundleContext context) throws Exception {
    		saveConf();
    		super.stop(context);
    		plugin = null;
    	}
     
    	/**
             * Returns the shared instance.
             */
    	public static ADTREEPlugin getDefault() {
    		return plugin;
    	}
     
    	/**
             * Returns an image descriptor for the image file at the given
             * plug-in relative path.
             *
             * @param path the path
             * @return the image descriptor
             */
    	public static ImageDescriptor getImageDescriptor(String path) {
    		return AbstractUIPlugin.imageDescriptorFromPlugin("ADTREE", path);
    	}
     
     
    	/**
             * Get the URL of a resource in the plugin.
             * @param path  Path relative to the plugin.
             * @return              Matching URL.
             */
    	public static URL getResourceURL(String path) {
    		return FileLocator.find(ADTREEPlugin.getDefault().getBundle(), new Path(path), null);
    	}
     
     
    	/**
             * Save the state of the plugin.
             */
    	private void saveConf() {
     
    		// save WCETs
    		saveProgConf();
     
    		// save configuration
    		XMLMemento memento = XMLMemento.createWriteRoot(PLUGIN_TAG);
    		saveConf(memento);
     
    		FileWriter writer = null;
    		try {
    			writer = new FileWriter(getConfFile());
    			memento.save(writer);
    		}
    		catch(IOException e) {
    			logError("cannot save the configuration", e);
    		}
    		finally {
    			if(writer != null)
    				try {
    					writer.close();
    				} catch (IOException e) {
    					logError("cannot close configuration", e);
    				}
    		}
    	}
     
    	/**
             * Get the configuration file.
             * @return      Configuration file.
             */
    	private java.io.File getConfFile() {
    		return plugin.getStateLocation().append("conf.xml").toFile();
    	}
     
    	/**
             * Save the configuration in the given memento.
             * @param memento       Memento to save in.
             */
    	private void saveConf(XMLMemento memento) {
    		IMemento child = memento.createChild(RECENTS_TAG);
    		for(String file : recent_files) {
    			IMemento mem = child.createChild(RECENT_TAG);
    			mem.putTextData(file);
    		}
    	}
     
    	/**
             * Load the configuration from a memento.
             * @param memento       Memento to load.
             */
    	private void loadConf(XMLMemento memento) {
    		IMemento[] children = memento.getChildren(RECENTS_TAG);
    		recent_files.clear();
    		if(children.length != 0) {
    			IMemento[] files = children[0].getChildren(RECENT_TAG); 
    			for(int i = 0; i < files.length; i++)
    				recent_files.addLast(files[i].getTextData());
    		}
    	}
     
    	/**
             * Load the configuration.
             */
    	private void loadConf() {
    		FileReader reader = null;
    		try {
    			reader = new FileReader(getConfFile());
    			XMLMemento memento = XMLMemento.createReadRoot(reader); 
    			loadConf(memento);
    		} catch (FileNotFoundException e) {
    			logInfo("configuration does not exists: default configuration");
    		} catch (WorkbenchException e) {
    			logError("bad configuration file", e);
    		}
    		finally {
    			if(reader != null)
    				try {
    					reader.close();
    				} catch (IOException e) {
    					logError("cannot close configuration", e);
    				}
    		}
    	}
     
    	/**
             * Add a file to the list of recent files.
             * @param file  File to add.
             */
    	public void addRecentFile(String file) {
    		if(recent_files.contains(file))
    			recent_files.remove(file);
    		else if(recent_files.size() >= RECENT_CAPACITY)
    			recent_files.removeLast();
    		recent_files.addFirst(file);
    	}
     
    	/**
             * Get the collection of recent files.
             * @return      Recent files collection.
             */
    	public Collection<String> getRecentFiles() {
    		return recent_files;
    	}
     
    	/**
             * Log an error.
             * @param message       Message to display.
             * @param exn           Exception causing the error.
             */
    	public static void logError(String message, Throwable exn) {
    		plugin.getLog().log(
    			new Status(IStatus.ERROR, PLUGIN_TAG, IStatus.OK, message, exn));
    	}
     
    	/**
             * Log an information.
             * @param message       Message to display.
             */
    	public static void logInfo(String message) {
    		plugin.getLog().log(
    			new Status(IStatus.INFO, PLUGIN_TAG, IStatus.OK, message, null));
    	}
     
    	/**
             * Log an information.
             * @param message       Message to display.
             */
    	public static void logWarning(String message) {
    		plugin.getLog().log(
    			new Status(IStatus.WARNING, PLUGIN_TAG, IStatus.OK, message, null));
    	}
     
    	/**
             * Set the status bar message.
             * @param view  Current view.
             */
    	public void setStatusBarMessage(IViewPart view, String message) {
    		IActionBars bars = view.getViewSite().getActionBars();
    		bars.getStatusLineManager().setMessage(message);
    	}
     
    	/**
             * Display an error dialog.
             * @param message       Message to display.
             */
    	public void doErrorDialog(String message) {
    		Status status = new Status(IStatus.ERROR, "OTAWA Plugin", 0,
    	            message, null);
    	        ErrorDialog.openError(Display.getCurrent().getActiveShell(),
    	            "JFace Error", "The program encountered a problem", status);
    	}
     
    	/**
             * Root of event classes.
             */
    	public static class Event { }
     
    	/**
             * Event class fire refreshing the property view.
             */
    	private static class PropRefreshEvent extends Event { }
     
    	//------------------------------------------------------------------------------
     
    	/**
             * Get the list of programs.
             * @return      Iterable on programs.
             */
    	public Iterable<Prog> getPrograms() {
    		return progs;
    	}
     
    	/**
             * Find a program by its name.
             * @param path          Path of the code.
             * @return                      Program or null if not found.
             */
    	public Prog getProgram(IFile file) {
    		for(Prog p:progs)
    			if(p.file.equals(file))
    				return p;
    		return null;
    	}
     
    	/**
             * Build a new program.
             * @param path          Path to project.
             * @param project       Project containing it (may be null).
             * @return                      Created program.
             */
    	public Prog obtainProgram(IFile file, WorkSpace ws) {
    		Prog prog = getProgram(file);
    		if(prog == null) {
    			prog = new Prog(file, ws);
    			progs.add(prog);
    		}
    		return prog;
    	}
     
    	/**
             * Save a program in the configuration.
             */
    	private void saveProgConf() {
    		for(Prog prog: progs)
    			prog.save();
    	}
     
    	/**
             * Get the file matching the given absolute path.
             * @param path  Absolute path.
             * @return              Matching IFile.
             */
    	public IFile getFile(String path) {
    		IPath ipath = new Path(path);
    		IFile res = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(ipath);
    		if(res == null)
    			res = ResourcesPlugin.getWorkspace().getRoot().getFile(ipath);
    		return res;
    	}
     
     
    	/** 
             * Initializes a preference store with default preference values 
             * for this plug-in.
             */
    	protected void initializeDefaultPreferences(IPreferenceStore store) {
    		store.setDefault(BAD_WORDS_PREFERENCE, DEFAULT_BAD_WORDS);
    		Color color= Display.getDefault().getSystemColor(DEFAULT_HIGHLIGHT);
    		PreferenceConverter.setDefault(store,  HIGHLIGHT_PREFERENCE, color.getRGB());
    	}
     
    	/**
             * Add a listener on plug-in events.
             * @param listener      Listener to add.
             */
    	public void addListener(Listener listener) {
    		listeners.add(Listener.class, listener);
    	}
     
    	/**
             * Remove a listener on plug-in events.
             * @param listener      Listener to remove.
             */
    	public void removeListener(Listener listener) {
    		listeners.remove(Listener.class, listener);
    	}
     
    	/**
             * Add a program.
             * @param prog  Program to add.
             */
    	public void addProgram(Prog prog) {
    		progs.add(prog);
    		for(Listener listener: listeners.getListeners(Listener.class))
    			listener.onProgramOpen(prog);
    	}
     
    	/**
             * Remove a program.
             * @param prog  Program to remove.
             */
    	public void removeProgram(Prog prog) {
    		prog.close();
    		progs.remove(prog);
    	}
     
        /**
         * @Author spiquel
         * @Date 7 Apr 2009
         * @param listener
         * @Description Add a colorize listener.
         */
    	public void addColorizeListener(ColorizeListener listener) {
    		listeners.add(ColorizeListener.class, listener);
    		listener.setColorization(colorize, colorized_task);
    	}
     
    	/**
             * @Author spiquel
             * @Date 7 Apr 2009
             * @param listener
             * @Description Remove a colorize listener.
             */
    	public void removeColorizeListener(ColorizeListener listener) {
    		listeners.remove(ColorizeListener.class, listener);
    	}
     
    	/**
             * @Author spiquel
             * @Date 7 Apr 2009
             * @return
             * @Description Test if colorization is enabled.
             */
    	public boolean isColorizationEnabled() {
    		return colorize;
    	}
     
    	/**
             * Fire an event of colorization.
             * @param enabled       True for enabling colorization, false else.
             * @param part          Part emitting the colorization.
             */
    	public void setColorization(boolean enabled) {
    		if(colorize == enabled)
    			return;
    		colorize = enabled;
    		for(ColorizeListener listener: listeners.getListeners(ColorizeListener.class))
    			listener.setColorization(enabled, colorized_task);
    	}
     
    	/**
             * Refresh the colorization.
             */
    	public void refreshColorization() {
    		for(ColorizeListener listener: listeners.getListeners(ColorizeListener.class))
    			listener.refresh();		
    	}
     
    	/**
             * Change the colorized task.
             * @param task  Set task.
             */
    	public void setColorizedTask(Task task) {
    		if(task == colorized_task)
    			return;
    		colorized_task = task;
    		for(ColorizeListener listener: listeners.getListeners(ColorizeListener.class))
    			listener.changeTask(task);		
    	}
     
    	/**
             * Return the current colorized task.
             */
    	public Task getColorizedTask() {
    		return colorized_task;
    	}
     
    	/**
             * Listener about events on the plug-in.
             */
    	public static interface Listener extends EventListener {
     
    		/**
                     * Called when a program is opened.
                     * @param prog  Opened program.
                     */
    		void onProgramOpen(Prog prog);
     
    	}
    }
    Et la classe Otawa, avec idLABEL() ligne 37

    Code : 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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    /*
     * ADTREE -- OTAWA plugin for Eclipse
     * 
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License along
     * with this program; if not, write to the Free Software Foundation, Inc.,
     * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.package ojawa;
     */
    package ojawa;
     
    /**
     * Static ressources available in the otawa namespace.
     * @author casse
     */
    public abstract class Otawa {
     
    	// Natives
    	public static native long idLABEL();
    	public static native long idFUNCTION_LABEL();
    	public static native long idIPET_WCET();
    	public static native long idENTRY_TASK();
     
    	/**
             * Identifier of labels put on the program items.
             */
    	public static final Identifier LABEL =
    		Identifier.get(idLABEL());
     
    	/**
             * Identifier of function labels put on the program items.
             */
    	public static final Identifier FUNCTION_LABEL =
    		Identifier.get(idFUNCTION_LABEL());
     
    	/**
             * Identifier of "otawa::ipet::wcet" (type int, default -1), put on workspace and
             * containing the WCET value after computation.
             */
    	public static final Identifier IPET_WCET =
    		Identifier.get(idIPET_WCET());
     
    	/**
             * Identifier for "otawa::entry_task" (type cstring, default "main"),
             * put on the configuration property list of the processors and giving the
             * name of the task entry point. 
             */
    	public static final Identifier ENTRY_TASK =
    		Identifier.get(idENTRY_TASK());
     
    	/**
             * Get the current OJAWA version.
             * @return      Current version.
             */
    	public static native String version();
     
    	/**
             * Get the compilation date.
             * @return      Compilation date.
             */
    	public static native String date();
     
    }
    Et le fichier Identifier.java, pour la classe Identifier (Identifier.get ligne 62, nat_get ligne 45).
    Le get appelé par public static Identifier get est ligne 70 (juste en dessous).

    Code : 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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    /*
     * ADTREE -- OTAWA plugin for Eclipse
     * 
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License along
     * with this program; if not, write to the Free Software Foundation, Inc.,
     * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.package ojawa;
     */
    package ojawa;
     
    /**
     * Accessor to an OTAWA identifier.
     * @author casse
     */
    public class Identifier extends PropList {
    	static Identifier IDENTIFIER_LABEL,
    					  IDENTIFIER_DESC;
     
    	// Object cache
    	private static final ObjectCache<Identifier> cache =
    		new ObjectCache<Identifier>() {
    			public Identifier make(long ptr) {
    				return new Identifier(ptr);
    			}
    		};
     
    	// fields	
    	String _name, label, desc;
    	Type _type;
     
    	// Natives
    	private static native String name(long ptr);
    	private static native long type(long ptr);
    	private static native String value(long ptr, long prop);
    	protected static native long nat_get(String name);
     
    	/**
             * Build a new identifier.
             * Do not call it unless you know what you do.
             * @param ptr   Pointer to the C++ pointer.
             */
    	protected Identifier(long ptr) {
    		super(ptr);
    	}
     
    	/**
             * Get an identifier by its name.
             * @param name  Name of the looked identifier.
             * @return              Found identifier or null.
             */
    	public static Identifier get(String name) {
    		return get(nat_get(name));
    	}
     
    	/**
             * Get an identifier by its pointer.
             * @param ptr   C++ identifier pointer.
             * @return              Matching identifier.
             */
    	static Identifier get(long ptr) {
    		return cache.get(ptr);
    	}
     
    	/**
             * Get the name of the identifier.
             * @return      Identifier name.
             */
    	public String getName() {
    		if(_name == null)
    			_name = name(ptr);
    		return _name;
    	}
     
    	/**
             * Get the type name of an identifier.
             * @return      Type of the identifier.
             */
    	public Type getType() {
    		if(_type == null)
    			_type = Type.get(type(ptr));
    		return _type;
    	}
     
    	/**
             * Get the value of a property matching the identifier.
             * @param p             Used property.
             * @return              Property value.
             */
    	public String getValue(Property p) {
    		return value(ptr, p.ptr);
    	}
     
    	/**
             * Get the label for the given identifier.
             * @return      Label.
             */
    	public String getLabel() {
    		if(label == null) {
    			if(IDENTIFIER_LABEL == null) {
    				IDENTIFIER_LABEL = Identifier.get("otawa::IDENTIFIER_LABEL");
    				assert IDENTIFIER_LABEL != null;
    			}
    			Property prop = getProp(IDENTIFIER_LABEL);
    			if(prop == null)
    				label = getName();
    			else
    				label = prop.getCString();
    		}
    		return label;
    	}
     
    	public String getDescription() {
    		if(desc == null) {
    			if(IDENTIFIER_DESC == null) {
    				IDENTIFIER_DESC = Identifier.get("otawa::IDENTIFIER_DESC");
    				assert IDENTIFIER_DESC == null;
    			}
    			Property prop = getProp(IDENTIFIER_DESC);
    			if(prop == null)
    				desc = "";
    			else
    				desc = prop.getCString();			
    		}
    		return desc;
    	}
    }
    PS : le problème du forum, c'est que je vais même pas pouvoir vous offrir le café pour l'aide.

  13. #13
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public abstract class Otawa {
     
    	// Natives
    	public static native long idLABEL();
    	public static native long idFUNCTION_LABEL();
    	public static native long idIPET_WCET();
    	public static native long idENTRY_TASK();
     
    	/**
             * Identifier of labels put on the program items.
             */
    	public static final Identifier LABEL =
    		Identifier.get(idLABEL());
    cherchez pas plus loin. Voilà ce qui risque de se passer (tot ou tard).

    A un moment que vous ne pouvez pas prévoir vous même (c'est impossible à prévoir, ce comportement n'est pas documenté nulle part), la JVM aura besoin d'initialiser votre classe. Pour ce faire, elle va lire dans l'ordre tous les bloc d'initialisation statique (l'indicateur <clinit> que vous voyez dans votre stacktrace), va tomber sur l'instruction idLabel(), tenter de l'exécuter et... oups erreurs la librairie n'est pas encore chargée.

    Tout code nécessaire à l'initialisation statique d'une classe doit se trouver dans ladite classe:
    Code : 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 abstract class Otawa {
     
    	// Natives
    	public static native long idLABEL();
    	public static native long idFUNCTION_LABEL();
    	public static native long idIPET_WCET();
    	public static native long idENTRY_TASK();
            // load librairy
            static {
     
    // link with OJAWA
    		try {
    			if(os.startsWith("Windows")){
    				System.load(dirpath+"libxml2.dll");
    				System.load(dirpath+"iconv.dll");
    				System.load(dirpath+"zlib1.dll");
    				System.load(dirpath+"libexslt.dll");
    				System.load(dirpath+"libxslt.dll");
    			}
    				System.load(path);
    				logInfo("using relocated OJAWA from " + path);
    		}
    		catch(java.lang.UnsatisfiedLinkError e) {
    			logInfo("can not find relocated OJAWA at " + path + ": attempting from libraries of LD_LIBRARY_PATH.");
    			e.printStackTrace();
    			if(os.equals("Linux"))
    				System.loadLibrary("ojawa");
    			else if(os.startsWith("Windows"))
    				System.loadLibrary("libojawa");
    		}
            }
     
    	/**
             * Identifier of labels put on the program items.
             */
    	public static final Identifier LABEL =
    		Identifier.get(idLABEL());

  14. #14
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut
    Merci beaucoup.
    Je passerais en Résolu d'ici peu, le temps de tester.

  15. #15
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Bon je viens de relire. Pas certain que ça résolve le problème vu le stacktrace, mais ça ne peux pas être une mauvais chose, pour éviter les ennuis.


    Pour le manque de doc, j'aurais tendance à dire qu'il y a une bonne raison à ca, JNI est une crasse intégrale pour ce que j'en juge des autres POSTS du forum . Sans connaitre votre application en arrière plan, est-ce que JNA (réputé plus facile à gérer) ne serait pas une solution acceptable pour lui. En "gros", JNA permet d'appeler des méthodes native sans avoir besoin d'écrire un code spécifique coté natif (on charge une librairie, on appel la méthode X de cette librairie). A voir donc

    Que je sache pour l'avoir vu utilisé dans le plugin eclipse svn, il existe des dépendance JNA qu'on peux ajouter dans eclipse, donc aucun travail à réaliser de ce coté là.

  16. #16
    Membre émérite
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Par défaut
    Bonjour,

    Je n'ai pas fais de test où je charge la dll dans une classe possédant des méthodes statiques natives, l'inverse ne m'a jamais pas poser de problème.
    Au contraire, ca me semble périlleux de mettre le chargement de la DLL dans la même classe que les méthodes statiques pour des questions d'ordre d'initialisation (DLL/classe)

    Je m'assure juste que la DLL soit bien chargée avant que j'utilise ma classe porteuse de méthodes natives, avant que la JVM cherche dans les DLL chargée la méthode correspondante.

    D'expérience récente, la galère au niveau des JNI réside au niveau des options de compilation. J'ai rencontré ces UnsatisfiedLinkError en raison d'une option de compilation.

    Alors, tu utilises quel compilateur?
    Vu que tu portes du code LINUX, est-ce que tu utilises par hasard gcc avec genre MinGW?

    Si tel est le cas, il y a une option importante à passer au compilateur (plus exactement au linker) pour la génération de la DLL : -Wl,--kill-at
    Voir : http://www.mingw.org/node/41

    Sans ceci, tu te retrouves avec des problèmes de convention d'export des fonctions dans la DLL
    => La dll se charge bien, mais la JVM ne trouve pas la fonction native qu'elle recherche
    => La JVM balance un UnsatisfiedLinkError

    Si ça peut t'aider, voici

    Un exemple de compilation à l'aide de GCC (MinGW)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -Wall -Wl,--kill-at -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared -o monpackage.dll monpackage_Beeper.cpp
    => monpackage.dll


    Un exemple de chargement de cette dll

    Code : 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
     
    package monpackage;
     
    public class BeeperTest {
     
    	static {
    		try{
    			//chargement de la DLL, si
    			System.loadLibrary("monpackage");
    		}catch( Exception e ){
    			System.err.println("impossible de charger monpackage.dll (recherche dans PATH et execution)");
    			e.printStackTrace();
    		}
    	}
     
     
    	public static void main( String argv[] ){
    		Beeper beeper = new Beeper();
    		beeper.beep(440,500);
    	}
    }
    La classe Beep avec sa méthode native

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    package monpackage;
     
    public class Beeper {
     
    	public native void beep( int frequency, int duration );
     
    }
    Le nom de la fonction dans "Dependency Walker"
    Java_monpackage_Beeper_beep
    (sans _Java, sans @16 à la fin)

    C'est sur la base de ce nom que la JVM retrouve la fonction dans la DLL


    Quelques remarques en vrac :
    - en général, on charge les dll en considérant qu'elles sont dans le répertoire d'exécution ou dans le path (pas besoin de chemin absolu)
    - inutile de faire porter l'extension dll ou so dans System.loadLibrary("otowa")
    - Si otowa dépend d'autres dll, windows se chargera de les trouver et de les charger quand tu chargeras "otowa.dll"
    - Je peux te zipper le reste de ces morceaux d'exemple qui font un joli LA de 500ms (build.bat, test.bat)
    - Je te conseillerais de commencer par un exemple très simple sous windows pour résoudre les problèmes de compilation et chargement : Beep, c'est pratique
    - Je crois guère en la magie de JNA, mais plus à celle de SWIG

    Bye,
    en espérant que ça t'éclaire un peu

  17. #17
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Citation Envoyé par bretus Voir le message

    Je m'assure juste que la DLL soit bien chargée avant que j'utilise ma classe porteuse de méthodes natives, avant que la JVM cherche dans les DLL chargée la méthode correspondante.
    Et le seul moyen en java de garantir ça dans 100% des cas, c'est de mettre ce code au début de l'initialisation statique de la classe, car l'initialisation statique de la classe est la seule chose que te garanti la JVM avant d'utiliser ta classe. Si l'application est plus ou moins complexe, impossible de prévoir à 100% quand sera fait un appel à Classloader.loadClass(), et par voie de conséquence, presque impossible de garantir le loadlibrary avant. On parle ici d'un plugin eclipse, peut etre que demain un autre plugin eclipse reposera dessus et fera "bêtement" quelque par un LaClasseNative.getClass().getName(), naivement, avant que le plugin ne soit initialisé. Et bardaf!

    Maintenant on est loin du problème de départ je l'admet, c'est juste un avis

  18. #18
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut
    Bonjour !
    Après discussion au sommet, voilà ce qui en est ressorti.
    Pas changement pour JNA.

    Je ne peux pas faire le chargement en static, pour des questions de retour d'information (j'avoue n'avoir pas tout compris).

    Je compile avec minGW, et j'ai rajouté -Wl,--kill-at dans les options pour ma dll.
    Otawa dépend bien d'autres dll, que je charge manuellement pour certaines, car j'ai des problèmes de path. J'ai au moins dix versions de libxml2.dll sur ma machine (snif), et la première dans mon path n'est pas celle que j'utilise pour compiler mes dll (et est incompatible). Donc pour éviter tout autre souci, j'ai inclus certaines dll au projet.


    J'ai modifié LABEL et ses amis (idFUNCTION_LABEL() idIPET_WCET() idENTRY_TASK() )comme ceci :

    Code : 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
    	private static native long idLABEL();
     
    	/**
             * Identifier of labels put on the program items.
             */
    	//public static final Identifier LABEL =
    	//	Identifier.get(idLABEL());
     
    	/**
             * Initializing idLABEL() on first call.
             */
    	public static long getLABEL(){
    		if(((Long)idLABEL()).equals(null))
    			idLABEL();
    		return idLABEL();
    	}
    Résolvant ainsi les problèmes d'appels pour ces variables (ou en tout cas j'ai plus d'erreur pour l'instant ).

    Me reste deux problèmes, venant du même fichier, Otawa.java (celui où est déclaré idLABEL().

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	/**
             * Get the current OJAWA version.
             * @return      Current version.
             */
    	public static native String version();
     
    	/**
             * Get the compilation date.
             * @return      Compilation date.
             */
    	public static native String date();
     
    }
    Le message d'erreur ressemble aux précédents, une UnsatisfiedLinkError, sauf que là, la méthode utilisée pour les précédents ne marche pas.

    Code : 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
    !ENTRY org.eclipse.osgi 4 0 2011-05-19 10:40:37.413
    !MESSAGE An error occurred while automatically activating bundle OTAWA (759).
    !STACK 0
    org.osgi.framework.BundleException: Exception in adtree.ADTREEPlugin.start() of bundle OTAWA.
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:806)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:755)
    [......]
    	at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
    	at org.eclipse.equinox.launcher.Main.main(Main.java:1384)
    Caused by: java.lang.UnsatisfiedLinkError: ojawa.Otawa.version()Ljava/lang/String;
    	at ojawa.Otawa.version(Native Method)
    	at adtree.ADTREEPlugin.start(ADTREEPlugin.java:235)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:783)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:774)
    	... 77 more
    Root exception:
    java.lang.UnsatisfiedLinkError: ojawa.Otawa.version()Ljava/lang/String;
    	at ojawa.Otawa.version(Native Method)
    	at adtree.ADTREEPlugin.start(ADTREEPlugin.java:235)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:783)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:774)
    [......]
    	at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
    	at org.eclipse.equinox.launcher.Main.main(Main.java:1384)
    Je les trouve bien dans Dependency Walker, je n'ai aucune idée de ce qui pourrait causer le problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Java_ojawa_Otawa_date@8
    Java_ojawa_Otawa_version@8

  19. #19
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 627
    Par défaut
    J'ai fait quelques tests, en fait même avec la nouvelle configuration idLABEL() me renvoie un UnsatisfiedLinkError().

    Et je ne peux pas "déplacer" le chargement des bibliothèques dans Otawa.java, car j'ai besoin du BundleContext pour avoir le chemin courant.

  20. #20
    Membre émérite
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Par défaut
    L'option n'est pas passée correctement, les noms des fonctions sont toujours décorés dans la DLL

    Jete un oeil a ces deux thread :

    Celui ci détail les options et leurs significations

    http://rabbit-hole.blogspot.com/2007...-with-gcc.html

    Que je cite :
    The --kill-at flag to the linker ensures all symbols are exported undecorated, i.e. _my_func instead of _my_func@NN, which is the default when a function is declared as __stdcall. You could also use --add-stdcall-alias, which includes both versions of the symbol.
    -Posted by technomage


    Celui ci est plus concis

    http://stackoverflow.com/questions/4...-does-not-work

    (je t'envoie le zip quand free aura enfin fini de l'analyser...)

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. ToAsciiEx, comment cela marche ?
    Par mikyfpc dans le forum C++Builder
    Réponses: 2
    Dernier message: 17/02/2004, 22h39
  2. [MFC] list box : comment ça marche
    Par runn2 dans le forum MFC
    Réponses: 4
    Dernier message: 28/01/2004, 13h36
  3. [SYNEDIT] -> Comment ça marche ?
    Par MaTHieU_ dans le forum C++Builder
    Réponses: 2
    Dernier message: 18/01/2004, 20h11
  4. [TP][Turbo Vision] comment ça marche ??
    Par Costello dans le forum Turbo Pascal
    Réponses: 7
    Dernier message: 05/08/2003, 01h24
  5. [update][req. imbriquee] Comment ca marche ??
    Par terziann dans le forum Langage SQL
    Réponses: 3
    Dernier message: 11/07/2003, 13h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo