Trouble returning String from JNI method

I'm a JNI newbie who is going through the SUN online book on JNI and have put together the 2nd program example (right after "helloworld"), but it is not working right. It is supposed to prompt you for a string, then returns the string that you type in. Right now it compiles without error, but it returns only the first word that I type, not the whole sentence. What am I doing wrong?
Here's the code:
Prompt.java
package petes.JNI;
public class Prompt
    private native String getLine(String prompt);
    static
        System.loadLibrary("petes_JNI_Prompt");
    public static void main(String[] args)
        Prompt p = new Prompt();
        String input = p.getLine("Type a line: ");
        System.out.println("User typed: " + input);
}petes_JNI_Prompt.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class petes_JNI_Prompt */
#ifndef _Included_petes_JNI_Prompt
#define _Included_petes_JNI_Prompt
#ifdef __cplusplus
extern "C" {
#endif
* Class:     petes_JNI_Prompt
* Method:    getLine
* Signature: (Ljava/lang/String;)Ljava/lang/String;
JNIEXPORT jstring JNICALL Java_petes_JNI_Prompt_getLine
  (JNIEnv *, jobject, jstring);
#ifdef __cplusplus
#endif
#endifpetes_JNI_Prompt.c
#include <jni.h>
#include <stdio.h>
#include "petes_JNI_Prompt.h"
JNIEXPORT jstring JNICALL Java_petes_JNI_Prompt_getLine
  (JNIEnv *env, jobject this, jstring prompt)
     char buf[128];
     const jbyte *str;
     str = (*env)->GetStringUTFChars(env, prompt, NULL);
     if (str == NULL)
          return NULL;  /*  OutOfMemoryError already thrown */
     printf("%s", str);
     (*env)->ReleaseStringUTFChars(env, prompt, str);
     // assume here that user will ty pe in 127 or less characters
     scanf("%s", buf);
     return (*env)->NewStringUTF(env, buf);
}Thanks in advance!
/Pete

OK, I have something that works now by substituting fgets for scanf. I have two other questions:
1) Do I need to free the memory created in buf? Will it allocate memory every time the method is run? Or will it allocate only once on creation, and so is no big deal?
2) A minor question: When I run this program in eclipse, the prompt string is displayed in the console only after the input string is entered and displayed. It works fine when I run it from the command line however. I have a feeling that this is a problem with how Eclipse deals with native methods and perhaps nothing I can fix. Any thoughts?
Thanks
Pete
Addendum, the updated code:
#include <jni.h>
#include <stdio.h>
#include "petes_JNI_Prompt.h"
JNIEXPORT jstring JNICALL Java_petes_JNI_Prompt_getLine
  (JNIEnv *env, jobject this, jstring prompt)
     char buf[128];
     const jbyte *str;
     str = (*env)->GetStringUTFChars(env, prompt, NULL);
     if (str == NULL)
          return NULL;  /*  OutOfMemoryError already thrown */
     printf("%s", str);
     (*env)->ReleaseStringUTFChars(env, prompt, str);
     //scanf("%s", buf);
     fgets(buf, 128, stdin);
     return (*env)->NewStringUTF(env, buf);
}Message was edited by:
petes1234

Similar Messages

  • Call String from another method

    hey,
    Im pretty new to java and Im having problems with calling a String from another method
    I have two public voids, in one of them I have a String which I wanna use in another method.
    Thanks

    here is some of my code:
    public void getOrder() {
            try {
                DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
                Document doc = docBuilder.parse(new File("c:/orders.xml"));
                // normalize text representation
                doc.getDocumentElement().normalize();
                System.out.println("Root element of the doc is " + doc.getDocumentElement().getNodeName());
                // lees orders
                NodeList orderlijst = doc.getElementsByTagName("order_naam");
                System.out.println("totale aantal orders : " + orderlijst.getLength());
             //    Element orderitem = (Element) orderlijst.item(0);
    System.out.println("name=" + doc.getElementsByTagName("order_naam").item(0).getFirstChild().getNodeValue());
              String st =doc.getElementsByTagName("order_naam").item(0).getFirstChild().getNodeValue();
      public void createGUI () {
            this.removeAll();
            lbltest = new JLabel();
            lbltest.setBounds(20, 40, 150, 20);
            lbltest.setFont(new Font("Verdana", Font.BOLD, 12));
            this.add(lbltest);
        i want to use the String st in the jLabel in createGUI

  • Returning strings from Java- C JNI calls

    <newbie to JNI>
    I have an application written in Java that accesses a .DLL written in C. The .DLL does low-level communication to a hardware device. I've got it all working except for one little problem:
    For all of the functions I need to return an integer return code and for some of them I also need to return a string, such as a serial number, version string, or whatever.
    Try as I might, I can't find any information on how to return two values from a function call (pretty sure I can't in Java).
    SO, I tried to find out how to stuff the version string into a string object variable in the class object the DLL API is defined in. I can't figure out how to do that either...
    e.g. the following Java code:
    class LLDev {
    /* --- Load the .DLL -------------------- */
    static { System.loadLibrary("LLDev"); }
    /* --- Error Codes ---------------------- */
    public static final int LLDOk = 0;
    public static final int LLDInitErr     = -1;
    /* --- Public Variables ----------------- */
    public static String DLLVersion;
    /* --- Public Methods ------------------- */
    public native int InitLLDev();
    When I invoke LLDev.InitLLDev() from Java I want the C .DLL function Java_LLDev_InitLLDev to put the DLL Version string in the LLDev object's DLLVersion field and return an error code as the function result.
    Is this possible???? Is this the right way to do this?? I tried to define the API with methods that return strings instead of integer return codes but the customer using the class wants all of the methods to return a return code in case of some error (e.g. reading the serial number from the device could fail...)

    1. In general, the java way to deal with errors is by throwing exceptions, not using return codes. But OK, you are stuck with the user requirement.
    2. I suggest you have the native method take as an argument a java object which will accept a string as input. In other words, it has a string "setter".
    3. So in your native method, if the function succeeds, it writes your string result to that object, and you can futrther process it when the native method returns a "success" code.
    4. There are JNI methods for
    o looking up the class of a java object.
    o looking up the method of a java class.
    o invoking the method.

  • Return a string from a method: a problem in C++ but is it a problem in java

    I have a method which return a String from it as:
    String pattern(short i)
    String s="":
    if (i==1)
    s = "test1";
    else
    s = "test2";
    return s;
    Since s is a local vaariable to pattern(), does the code above
    create problems? I know it is a problem for C++ since the local
    variable memory address will be reused by others and thus the
    returned value may take other values sometime later or not
    readable.

    Actually, this is not a problem in C++ either if you
    just use the string class instead of the old-style
    char* from C.True, I was assuming he/she meant (in C++):
    char mylocalbuf[80];
    // put stuff in mylocalbuf here
    return mylocalbuf;
    which would be very very bad to do indeed.

  • Returning String[] from C program

    How can I return a string[] from a cprogram to a java program?
    private native String[] readRFIDData();
    JNIEXPORT jobjectArray JNICALL Java_RfidDM_readRFIDData
    (JNIEnv *, jobject);
    Above is the definition of a jni method .
    I have gone through the sample code, but they explain how to return arrays from C++.
    Can someone please suggest? I am not good at C.
    Much thanks,
    Ann

    Thanks Scott.
    This code works fine for me...
         jclass sclass = (*env)->FindClass(env, "java/lang/String");
         jobjectArray ret = (*env)->NewObjectArray(env, length, sclass, NULL);
         for(i=0;i<37;i++){
              (*env)->SetObjectArrayElement(
                   env,ret,i,(*env)->NewStringUTF(env,&buf));     
              printf(&buf[i]);

  • NEED HELP on returning values from a method

    Hello Java World,
    Does anyone know how to return more then 1 value from a method..
    ex.
    //the following returns one value
    //Person Class
    private String getname()
    return this.name;
    how can i get two values (ex. name and occupation of person)
    Thank you in advance.

    Create a Class which will hold the values you want and return that object. Or return a List, or return an array, or - taking your example with the person, why don't you return the whole person object?
    Thomas

  • Remote Object - not able to get the returned value from java method

         Hi ,
    I am developing one sample flex aplication that connects to the java code and displays the returned value from the
    java method in flex client. Here I am able to invoke the java method but not able to collect the returned value.
    lastResult is giving null .  I am able to see the sysout messages in server console.
    I am using flex 3.2 and blazeds server  and java 1.5
    Here is the code what I have written.
    <?xml version="1.0" encoding="utf-8"?><mx:WindowedApplication  xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="#FFFFFF" initialize="initApp()">
     <mx:Script><![CDATA[
    import mx.controls.Alert; 
    import mx.binding.utils.ChangeWatcher; 
    import mx.rpc.events.ResultEvent; 
    import mx.messaging.*; 
    import mx.messaging.channels.* 
    public function initApp():void { 
         var cs:ChannelSet = new ChannelSet(); 
         var customChannel:Channel = new AMFChannel("my-amf", "http://localhost:8400/blazeds/messagebroker/amf");     cs.addChannel(customChannel);
         remoteObj.channelSet = cs;
    public function writeToConsole():void {      remoteObj.writeToConsole(
    "hello from Flash client");
          var returnedVal:String = remoteObj.setName().lastResult;     Alert.show(returnedVal);
    //[Bindable] 
    // private var returnedVal:String; 
    ]]>
    </mx:Script>
    <mx:RemoteObject id="remoteObj" destination="sro" /> 
    <mx:Form width="437" height="281">
     <mx:FormItem>  
    </mx:FormItem>  
    <mx:Button label="Write To Server Console" click="writeToConsole()"/>
     </mx:Form>
     </mx:WindowedApplication>
    Java code
    public  
         public SimpleRemoteObject(){  
              super();     }
      class SimpleRemoteObject { 
         public void writeToConsole(String msg) {          System.out.println("SimpleRemoteObject.write: " + msg);     }
         public String setName(){          System.
    out.println("Name changed in Java"); 
              return "Name changed in Java";
    And I have configured destination in  remote-config.xml
    <destination id="sro">
       <properties>    
        <source>SimpleRemoteObject</source>
        <scope>application</scope>
       </properties>
      </destination>
    Please help me .

    You are not able to get the returned value because if you see the Remote object help you will realise you have to use result="resultfn()" and fault = "faultfn()"
    In this you define what you wish to do.
    More importantly in the remote object you need to define which method you wish to call using the method class like this
    <mx:RemoteObject id="remoteObj" destination="sro" result="r1" fault="f1"  >
         <Method name="javaMethodName" result="r2" fault="f2"/>
    <mx:RemoteObject>
    r2 is the function where you get the result back from java and can use it to send the alert.

  • The problem of return value from a method

    Hi everyone:
    I want return a value from following method. The basic idea is that I want use Num as a parameter to get a value from a field, therefore I can input this value into another database for the display purpose by using other classes. However I got error message when I compiled it.
    "method does not return a value"
    I know it is a problem, but how I can fix it? I need your help. Thanks in advance.
    Dawei
    Method:
    public int Read(int Num) {
    try{
    String qr1 = "select Record form Buffer where Record="+Num+"";
    ResultSet rs = statement.executeQuery(qr1);
    while (!rs.next()){
              int result=rs.getInt(1);
    return(result);
         catch (SQLException e){
                   System.err.println("Error in inserting into database " + e);
                        System.exit(1);
    return 1;

    "select Record form Buffer ...Hopefully "form" is actually "from" in your code.
    You have three points of exit from your routine, and only two return value statements.
    1 -Return inside the while loop has a value.
    2- Return inside the exception block (not sure that '1' would be a valid number)
    3- The very end of the method, just before the last '}' does not have a return statement.
    By the way, this question has nothing to do with JDBC, so another forum might be a better place to post it.

  • Can I get 2 return datatypes from a method?

    I am looking to get a int from a method but also need a boolean value to indicate if it is a valid number which is tested in my method. If it is allowed must I declare the method twice for each datatype?
    Edited by: Yucca on Apr 19, 2008 5:26 PM

    Hi jverd. This is part of my program from last night. I do test in the method for valid value and throw an exception. However if I leave it at that it will still update my object with value and furthe update my ArrayList with the onject. This is not correct. As u see in my code I am already testing my arrayList with a boolean value and find that if I continue so it will be beneficial as I still have 2 more datatypes that need to be tested.
    public void createNew()
         { // start of createNew()
              Person p = new Person();
              String firstName = getName("Create");
              String lastName = getSurname();
              int homeNum = getHome();
              int count =0;
              boolean found = false;
              //Test if the contact is in phonelist already
              for(Person c: phoneList)
                   c = phoneList.get(count);
                   if((c.name).equals(firstName.trim().toUpperCase())&&(c.surname).equals(lastName.trim().toUpperCase()))
                        JOptionPane.showMessageDialog(null,"You may not enter duplicate contacts. \nPlease abbreviate or change the contacts name/surname.","Error",JOptionPane.ERROR_MESSAGE);
                        found = true;
                        createNew();
                        break;
                   count ++;
              // If contact is not in list the update it
              if(found == false)
                   p.name = firstName.trim().toUpperCase();
                   p.surname = lastName.trim().toUpperCase();
                   phoneList.add(p);
    public int getHome()
              int homeNum = 0;
              String home = JOptionPane.showInputDialog(null,"Please enter the contacts home number or press cancel to exit.");
              //If a string was entered make sure it is a integer
              if(home.length() > 0)
                   try
                        homeNum = Integer.parseInt(home);
                   catch(NumberFormatException nfe)
                        JOptionPane.showMessageDialog(null,"You may not use letters as a phone number. Please try again","Error",JOptionPane.ERROR_MESSAGE);
              return homeNum;
         }I want the getHome method to return a boolean value to and pass it up to the part where I test for corectness before updating the arrayList.

  • Returning strings from OLE2 Word object (Forms 4.5)

    Below is an example of how to return string and numeric values from OLE2 objects. In this example the OLE2 object is a MS Word document, and I want to fetch all the bookmarks in the Document into a Forms 4.5 Varchar2. To do this I first need to get the count of bookmarks.
    Getting a string property from an OLE2 object is a common OLE2 requirement but is poorly documented. This is the ONLY way it can be done, as OLE2.INVOKE_CHAR returns a single character not a string. Use OLE2.INVOKE_OBJ, then OLE2.GET_CHAR_PROPERTY which does return a string, as shown below, to return a string from an OLE object (or OLE property).
    Also note how you can only get the child object from its parent, not the grandchild (etc) object, so multiple (cascading) GET_OBJ_PROPERTY calls are required.
    /* by: Marcus Anderson (Anderson Digital) (MarcusAnderson.info) */
    /* name: Get_Bookmarks */
    /* desc: Returns a double quoted CSV string containing the document*/
    /* bookmarks. CSV string will always contain a trailing comma*/
    /* EG: "Bookmark1","Bookmark2",Bookmark3",Bookmark4", */
    /*               NB: This requires that Bookmarks cannot contain " chr */
    PROCEDURE Get_Bookmarks (pout_text OUT VARCHAR2)
    IS
    v_text           VARCHAR2(80);
    v_num                         NUMBER(3);
         v_arglist OLE2.LIST_TYPE;
         v_Application     OLE2.OBJ_TYPE;
    v_ActiveDoc      OLE2.OBJ_TYPE;
    v_Bookmarks          OLE2.OBJ_TYPE;
    v_Item                    OLE2.OBJ_TYPE;
    v_i                              NUMBER(3);
    BEGIN
              v_Application     := LDWord.MyApplication; -- Word doc opened elsewhere
                   /* Set v_num = ActiveDocument.Bookmarks.Count */
    v_ActiveDoc := OLE2.GET_OBJ_PROPERTY (v_Application, 'ActiveDocument');
    v_Bookmarks := OLE2.GET_OBJ_PROPERTY (v_ActiveDoc , 'Bookmarks');
    v_num := OLE2.GET_NUM_PROPERTY (v_Bookmarks, 'Count'); -- NB: Returns numeric property
                   /* Build the output string, pout_text. */
    FOR v_i in 1..v_num LOOP
                        /* Set v_item = ActiveDocument.Bookmarks.Item(v_i) */
    v_arglist := OLE2.CREATE_ARGLIST;
    OLE2.ADD_ARG (v_arglist, v_i);
    v_Item := OLE2.INVOKE_OBJ (v_Bookmarks, 'Item', v_arglist); -- NB: returns parent object (array element)
    OLE2.DESTROY_ARGLIST (v_arglist);
                        /* Set v_text = ActiveDocument.Bookmarks.Item(v_i).Name */
    v_text := OLE2.GET_CHAR_PROPERTY (v_Item, 'Name');                    -- NB: Returns string/varchar2 property
    pout_text := pout_text || '"' || v_text || '",' ;
    END LOOP;
    END;

    Please repost in the Forms discussion forum.
    - OTN

  • Why returning string from java stored function failed ?  HELP ME, PLEASE

    Hi everybody,
    I created java stored function: it's doing http post, parsing xml from http reply, and returning string result.
    Sometimes, it doesn't return any value. What can be a reason ?
    The high level procedure, has following form:
    class SBE {
    public static String call(String arg0) {
    SBE sbe=new SBE("d:\\oracle\\ora81\\network\\log\\SBE.log");
    String result=SBEParser.go(sbe.sendRequest(arg0, ""), sbe.logger);
    sbe.logger.log(result);
    sbe.logger.log("Finish SBE intetraction");
    return result;
    PLSQL wrapper has a simple form:
    create or replace package PG_SBE as
    function CALL(arg0 in varchar2) return varchar2;
    end;
    create or replace package body PG_SBE as
    function CALL(arg0 varchar2) return varchar2 as language java name 'SBE.call(java.lang.String) return java.lang.String';
    end;
    In log file ("d:\\oracle\\ora81\\network\\log\\SBE.log"), I can find message :
    "Finish SBE intetraction"
    but query:
    select pg_sbe.call("any argument") from dual;
    doesn't finish.
    What can be a reason ? What can I do to trace stage of convertion java string to varchar ?
    Please help me...
    Best regards
    Marek

    <BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Stefan Fdgersten ([email protected]):
    Maybe your call is wrong... Shouldn't there be a "?" instead of "1"?
    Your code:
    String myquery = "begin :1 := jspTest; end;";
    I provide my (working) call from java as an example. Maybe it is of any help... :)
    import java.sql.*;
    import oracle.jdbc.driver.*;
    public Vector getAllHosts() throws SQLException {
    //return getHosts(false, -1);
    Connection conn = null;
    CallableStatement cs = null;
    Vector hostV = new Vector();
    try {
    conn = getConnection();
    String query = "{ ? = call curTestPkg.curTestFunc}";
    cs = conn.prepareCall(query);
    cs.registerOutParameter(1, OracleTypes.CURSOR);
    cs.execute();
    ResultSet rs = ((OracleCallableStatement)cs).getCursor(1);
    while (rs.next()) {
    Host host = new Host(
    rs.getInt("hostid")
    , rs.getString("name")
    , rs.getString("descr")
    , rs.getString("os"));
    hostV.add(host);
    cs.close();
    return hostV;
    } finally {
    close(conn, cs);
    <HR></BLOCKQUOTE>
    hi Stefan thanx.....even after changing the call statement i get the same error. i changed query string as...
    String myquery = "{ ? = call jspTest}";
    CallableStatement cst = con.prepareCall(myquery);
    Can u please check out my call sepc that i have written in pl/sql and plz let me know it there is any error in that.
    PS : THIS IS THE FIRST TIME I AM WORKING WITH PL/SQL AND IT IS URGENT

  • Why returning string from java stored function failed ?

    I created java stored function: it's doing http post, parsing xml from http reply, and returning string result.
    Sometimes, it doesn't return any value. What can be a reason ?
    The high level procedure, has following form:
    class SBE {
    public static String call(String arg0) {
    SBE sbe=new SBE("d:\\oracle\\ora81\\network\\log\\SBE.log");
    String result=SBEParser.go(sbe.sendRequest(arg0, ""), sbe.logger);
    sbe.logger.log(result);
    sbe.logger.log("Finish SBE intetraction");
    return result;
    PLSQL wrapper has a simple form:
    create or replace package PG_SBE as
    function CALL(arg0 in varchar2) return varchar2;
    end;
    create or replace package body PG_SBE as
    function CALL(arg0 varchar2) return varchar2 as language java name 'SBE.call(java.lang.String) return java.lang.String';
    end;
    In log file ("d:\\oracle\\ora81\\network\\log\\SBE.log"), I can find message :
    "Finish SBE intetraction"
    but query:
    select pg_sbe.call("any argument") from dual;
    doesn't finish.
    What can be a reason ? What can I do to trace stage of convertion java string to varchar ?
    Please help me...
    Marek

    This comes up periodically. It just isn't possible using that type of approach. Probably the best you could do is the create an ADT (containing collections) and use that to pass a 'batch' of information.
    Hopefully this will get addressed in the next release of the database.

  • Need to return String from C Program to Java

    I need to execute a C Program, which returns a string, from my java application. I was thinking of using RMI to execute this C program. Any idea ?

    There are lots of ways to do this. The simplist is probably for the C program to write it's output to a temporary file, and then have the java program read that file. Or, you could open a socket and pass the string that way (say, have your java program listen on a port and have the C program open a connection to the java program and write it's string).
    Hope that gives you a starter

  • Calling a pure C function from JNI method

    Is it posible to call a pure C function from a JNI method.?
    I am communicating with an external device whose API is written in C language.
    Would it work this way
    If I declare empty native methods in Java and those methods in C call pure C methods?
    Thank You...

    Hello,
    I have a similar problem and I posted it here http://www.velocityreviews.com/forums/t724826-jni-calling-an-outside-function-in-the-c-file-which-is-being-called-by-the-java-file.html. If you can answer the question, it would greatly help me.
    Thanks
    Nick

  • Why my method can not receive the string from JNI

    JNIEXPORT jstring JNICALL Java_playaudio_BeatTrack_myBeatTrack
    (JNIEnv *env, jobject obj, jstring wavfile)
    const char* filename = env->GetStringUTFChars(wavfile,0);
    BeatTrack(filename);
    env->ReleaseStringUTFChars(wavfile,filename);
    return NULL;
    }for my BeatTrack method, I just need the filename, then it can run, if I comment the BeatTrack(filename);, then no problem, for the java calling, of course, my BeatTrack(const *char filename) has no problem, cause I have test it,,
    but I call this method in java, the error is as follows,
    Java VM: Java HotSpot(TM) Client VM (10.0-b19 mixed mode, sharing windows-x86) # Problematic frame: # C [beattrack.dll+0x130b] # # An error report file with more information is saved as: # D:\programs\playAudio\hs_err_pid11684.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # The crash happened outside the Java Virtual Machine in native code. # See problematic frame for where to report the bug. any idea??

    1) What class is "missing?"
    2) Where is it?

Maybe you are looking for