Link to home
Start Free TrialLog in
Avatar of fjhst
fjhst

asked on

Plese help me! A problem about invoking java code in C++ Builder use JNI. Thanks!

Sorry, I am not good at English.


////////////////////////////////////////////////////////////////
//Index.java
////////////////////////////////////////////////////////////////
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.DateField;
import org.apache.lucene.analysis.*;

import org.apache.lucene.analysis.cn.*;
import org.apache.lucene.analysis.cn.ChineseAnalyzer;

import java.util.Hashtable;
import java.util.Date;
import java.io.File;
import java.io.Reader;
import java.io.FileInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.String;
import javax.swing.JOptionPane;

class FileDocument
{
  public static Document Document(File f)
       throws java.io.FileNotFoundException
  {

    Document doc = new Document();
    doc.add(Field.Text("path", f.getPath()));
    doc.add(Field.Keyword("modified",
                    DateField.timeToString(f.lastModified())));
    FileInputStream is = new FileInputStream(f);
    Reader reader = new BufferedReader(new InputStreamReader(is));
    doc.add(Field.Text("contents", reader));
    return doc;
  }

  private FileDocument() {}
}

public class Index
{
        public static void main(String args[])
        {
            File TxtFile;
            String AppPath = System.getProperty("user.dir")+"\\";
            String ResultFullPath = AppPath + "result.txt";
            
            TextPath = args[0];
            IndexPath = args[1];

            JOptionPane.showMessageDialog(null, TextPath+IndexPath, "alert", JOptionPane.ERROR_MESSAGE);
            
            try
            {
                  IndexWriter awriter = new IndexWriter(IndexPath, new StandardAnalyzer(), true);
                  indexDocs(awriter, new File(TextPath));
                  awriter.optimize();
                  awriter.close();
            } catch (Exception e)
            {
                    ;;
            }
        }
      public static void indexDocs(IndexWriter writer, File file) throws Exception
      {
        if (file.isDirectory())
        {
          String[] files = file.list();
          for (int i = 0; i < files.length; i++)
            indexDocs(writer, new File(file, files[i]));
        } else
        {
          System.out.println("adding " + file);
          writer.addDocument(FileDocument.Document(file));
        }
      }
}

Compile and run in command line success!

////////////////////////////////////////////////////////////////
//C++ Builder Code
////////////////////////////////////////////////////////////////

#define MAIN_CLASS  "Index"

void __fastcall TMainForm::Button1Click(TObject *Sender)
{
    char infor[255];
      jmethodID mid;
      jclass cls;
      int result;
      jint square;
      jboolean not;

    if(MainForm->jvm == NULL || MainForm->env == NULL) return;
      cls = MainForm->env->FindClass(MAIN_CLASS);
      if( cls != 0 )
    {
        mid = MainForm->env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
            if( mid!= 0 )
            {
                    int i= 1, ret;
                  jstring TxtFileName, IndexPath;
                  jobjectArray args;
                  char *WinStr;

                  WinStr = "E:\\\\GoleDic\\\\text\\\\";
                  TxtFileName = WindowsTojstring(MainForm->env, WinStr);

                  WinStr = "E:\\\\GoleDic\\\\index\\\\";
                  IndexPath = WindowsTojstring(MainForm->env, WinStr);

                  args= MainForm->env->NewObjectArray(2, MainForm->env->FindClass("java/lang/String"), 0);
                  MainForm->env->SetObjectArrayElement(args, 0, TxtFileName);
                  MainForm->env->SetObjectArrayElement(args, 1, IndexPath);

                  MainForm->env->CallStaticVoidMethod(cls, mid, args);
            }
    }
      return;
}


But when invoking the java code in C++ Builder,

"MainForm->env->FindClass(MAIN_CLASS)" return NULL, it can't find this class named "Index"!

when I change the java code to such this:

            ...
            
            try
            {
                  /*
                  IndexWriter awriter = new IndexWriter(IndexPath, new StandardAnalyzer(), true);
                  indexDocs(awriter, new File(TextPath));
                  awriter.optimize();
                  awriter.close();
                  */
            } catch (Exception e)
            {
                    ;;
            }
            
            ...
            
"MainForm->env->FindClass(MAIN_CLASS)" will find this class!

I should also mention the my knowledge in java and my english is very poor, so the answer could be something very simple!

Please advise, thanks!

Avatar of fjhst
fjhst

ASKER

why i just have 50 points? what does it mean?
Avatar of fjhst

ASKER

Plese Help Me!
Is this something related to the lucene classes?
How do you start the jvm? Are the lucene classes in the classpath?
Avatar of fjhst

ASKER

/////////////////////////////////////////////////////////
//Create Java Virtual machine:
/////////////////////////////////////////////////////////


void __fastcall TMainForm::FormCreate(TObject *Sender)
{
    jint ret = -1;
    HMODULE hLib;
    JavaVMInitArgs vm_args;
    JavaVMOption options[2];
    JNI_CREATEJAVAVM JNI_CreateJavaVM = NULL;

    Memo1->Clear();

    options[0].optionString = "-Djava.compiler=NONE";
    options[1].optionString = "-Djava.class.path=.";

    vm_args.version = JNI_VERSION_1_4;
    vm_args.options = options;
    vm_args.nOptions = 2;
    vm_args.ignoreUnrecognized = JNI_FALSE;

    MainForm->jvm = NULL;
    MainForm->env = NULL;

    hLib = LoadLibrary("C:\\Program Files\\Java\\j2re1.4.1_02\\bin\\client\\jvm.dll");
    if(hLib == NULL)
    {
        Memo1->Lines->Add("Can't load jvm.dll!");
        return;
    }

    /*Create Java VM*/
    JNI_CreateJavaVM = (JNI_CREATEJAVAVM) GetProcAddress(hLib, "JNI_CreateJavaVM");
    if(JNI_CreateJavaVM != NULL)
    {
        ret = (*JNI_CreateJavaVM)(&MainForm->jvm,(void**)&MainForm->env,&vm_args);
        if(ret<0)
        {
            MainForm->jvm = NULL;
            MainForm->env = NULL;
            Memo1->Lines->Add("Sorry,JVM is not set up!");
        }else
        {
            Memo1->Lines->Add("Hello,JVM!");
        }
    }
    else
    {
        Memo1->Lines->Add("Can't Get JNI_CreatJavaVM address!");
        return;
    }

    return;
}

/////////////////////////////////////////////////////////
//Destroy Java Virtual machine:
/////////////////////////////////////////////////////////
void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
    if(MainForm->jvm != NULL && MainForm->env != NULL)
    {
         MainForm->jvm->DestroyJavaVM();
    }
}

I am using the Windows 2000 profession, the AUTOEXEC.BAT file is:
set path=c:\j2sdk1.4.1_02\bin;%path%
set classpath=.;c:\j2sdk1.4.1_02\lib\tools.jar;.;C:\lucene\lucene.jar;
set JAVA_HOME=c:\j2sdk1.4.1_02
set PATH=%PATH%;%ANT_HOME%\bin

I checked the value and it contains the right directories.

Is there anything obvious in the code that is wrong?
Are the options OK?
Has anybody experienced the same behavior?

Any help or workaround will be greatly appreciated

Avatar of fjhst

ASKER

in addition, the main.h is:

class TMainForm : public TForm
{
__published:     // IDE-managed Components
    TButton *Button1;
    TMemo *Memo1;
    TButton *Button2;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall FormDestroy(TObject *Sender);
    void __fastcall Button2Click(TObject *Sender);
private:     // User declarations
     JNIEnv *env;
     JavaVM *jvm;
public:          // User declarations
    __fastcall TMainForm(TComponent* Owner);
};
Avatar of fjhst

ASKER

Anyone can download this project from here:
http://huatao.xiloo.com/GoleDic.rar
I think that this is the line that causes the problem:
options[1].optionString = "-Djava.class.path=.";

the class path must contain the lucene jar - otherwise you won't be able to load the MAIN_CLASS because it references some lucene classes. The line should be something like this:
options[1].optionString = "-Djava.class.path=.;c:/.../lucene.jar";


Avatar of fjhst

ASKER

but when I change the options[1].optionString  to
options[1].optionString = "-Djava.class.path=.; C:\lucene\lucene.jar";

MainForm->env->FindClass(MAIN_CLASS) also return NULL!
Avatar of fjhst

ASKER

options[1].optionString = "-Djava.class.path=.; C:/lucene/lucene.jar";

MainForm->env->FindClass(MAIN_CLASS) return NULL too!

ASKER CERTIFIED SOLUTION
Avatar of Venci75
Venci75

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of fjhst

ASKER

Let me try thus...
Avatar of fjhst

ASKER

yes, just only one class: lucene.jar
Avatar of fjhst

ASKER

I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!
I RESOLVE THIS PROBLEM!!!!!!!!!
thank you very much!!!!!!!!!!!!

fjhst:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
As I see from the fjhst's comment - the problem is resolved and since I was the only one participated in this question - I think that the solution was mine