2012-10-19 20 views
9

Sto scrivendo una libreria nativa java in C++ e utilizzo la gestione delle eccezioni all'interno della stessa lib nativa, ma la libreria si blocca non appena lancio un'eccezione. Ecco il mio semplice programma di test, quando lo chiamo dal test di Java, si blocca appena viene lanciata un'eccezione. Il blocco catch non funziona. Qualche idea su ciò che mi manca. Grazie.blocco catch non funziona nella libreria nativa C++

#include "Test.h" 
#include <iostream> 

JNIEXPORT void JNICALL Java_Test_helloWorld(JNIEnv *, jobject) 
{ 
    std::cout<<"Hello World"; 
    try { 
     throw 1; 
    } 
    catch(int) 
    { 
     std::cout<<" catch int block"<<std::endl; 
    } 
    catch(...) 
    { 
     std::cout<<" catch block"<<std::endl; 
    } 
} 

compilare e linkare:

g++ -m64 -fPIC -fexceptions -c test.cpp 
g++ -shared -m64 -Wl,-soname,libtest.so -Wl,-shared-libgcc test.o -o libtest.so 

$ java -d64 -Djava.library.path=/home/vkumar/projects/test -cp $CLASSPATH Test 
terminate called after throwing an instance of 'int' 
terminate called recursively 
Hello World^CAbort (core dumped) 
+0

quale piattaforma? quale venditore e versione di java? –

+0

SunOS 5.10, GCC 4.3.3 e JDK 1.6.0, ho provato a compilare tutto in modalità a 32 bit, ma gli stessi risultati. – vkumar

+1

Ricordo di aver avuto un problema simile alcuni anni fa su Solaris. Allora, il problema stava usando GCC, il linker GNU e le librerie condivise. Abbiamo risolto il problema utilizzando il linker Sun e collegando a file binari statici. Ovviamente, l'implementazione try/catch di GCC richiedeva il supporto del linker che non era compatibile con il linker dinamico di Sun. Si potrebbe provare a utilizzare un linker diverso, poiché l'andare statico non aiuterà in un ambiente Java. – h2stein

risposta

1

ho cercato il tuo examplea e tutto è andato bene. Il mio ambiente è Ubuntu 12.04 (64 bit) con Oracle JDK 1.7.

Quindi, la mia ipotesi è che il tuo ambiente è il colpevole. Poiché utilizzi l'opzione -m64, potrebbe trattarsi di una mancata corrispondenza tra il sistema a 32 bit e il libtest.so a 64 bit.

Verificare che il sistema, JDK, gcc, ecc. Si adattino tutti insieme.

+0

Grazie, controllerò la compatibilità tra tutti i componenti coinvolti. Sto usando Solaris 5.10, gcc 4.3.3 e jdk 1.6 – vkumar

+0

@vkumar Ho provato con OpenJDK 6 e OpenJDK 7 (gcc 4.6.3). Stesso risultato: successo. –

+0

Grazie Olaf, ho intenzione di provare con diverse versioni di GCC. Il nostro obiettivo prod env. è Sun Solaris, non sarei in grado di cambiarlo. Ma se il problema del compilatore, posso sempre aggiornarlo. Grazie ancora. – vkumar

0

Sembra che l'eccezione sia stata ignorata. Prova

int i=1; 

try { 
    throw i; 
} 

potrebbe esserci un problema con int dimensioni o qualcosa del genere? O ti sei dimenticato di ricompilare?

+0

No, mi sono assicurato che cancellassi .so, .o e ricompilassi tutto. anche se c'è un problema con la dimensione int, il pescato (...) dovrebbe prenderlo. – vkumar

0

JNIExport o JNICALL si espandono per definire il collegamento c? se è così allora stai lanciando un'eccezione C++ in una funzione c e non sono sicuro che il comportamento sia definito.

forse provare qualcosa di simile

namespace 
{ 
    void impl() 
    { 
    ... yourCode ... 
    } 
} 

JNIEXPORT void JNICALL Java_Test_helloWorld(JNIEnv *, jobject) 
{ 
    impl(); 
} 
+0

Non è un problema lanciare e rilevare un'eccezione in una funzione "C" esterna. Sarebbe un problema lasciare che l'eccezione sfugga alla funzione. –

Problemi correlati