How to Connect Server with JNI?
Hi There friends,
I have some problem. I have a server written in java and I need to send 5 double datatype values to C program using JNI(These values are obtained from the GUI client, this bridge between GUI client and Server is working fine....). So only after the client send these values the native method sholud be called and the values must then be sent to C program and then the C program will do some processing over those 5 double values and the new values of these 5 double datatype must be sent back to the server which then server will pass to my GUI client. Well friends I am not sure how should I go abt this communucation between server and the C program using JNI any help from u will really be appretiated any code or something of that sort. i am posting the code of my server here:
import java.net.*;
import java.io.*;
import java.lang.*;
import java.util.*;
public class DistillationServer
{
public static void main(String[] args)
{
//Initiallise the network connection
try
{
ServerSocket serverSocket = new ServerSocket(8200);
//now sit in a infinite loop until we get something
while(true)
{
//accept the message
Socket incoming = serverSocket.accept();
//spawn the thread to handle the request
DistillationThread th = new DistillationThread(incoming);
th.start();
}
}
catch(Exception ex)
{
System.out.println("Error: "+ex.toString());
}
}
}
class DistillationThread extends Thread
{
double pre, toplev, flo, botlev, temp;(these values will be sent to C program)
//The socket we are writing to
Socket incoming;
DistillationThread(Socket incoming)
{
this.incoming = incoming;
}
//run() method implemented by Thread class
public void run()
{
try
{
//get input from socket
BufferedReader input = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
//get output to socket
PrintStream output = new PrintStream(incoming.getOutputStream());
//now get input from server until it closes the connection
boolean finished = false;
while(!finished)
{
String newvalue = input.readLine();
//convert to a readable format
try
{
StringTokenizer stk = new StringTokenizer(newvalue, "|");
pre = Double.valueOf(stk.nextToken()).doubleValue();
toplev = Double.valueOf(stk.nextToken()).doubleValue();
flo = Double.valueOf(stk.nextToken()).doubleValue();
botlev = Double.valueOf(stk.nextToken()).doubleValue();
temp = Double.valueOf(stk.nextToken()).doubleValue();
//put our result on the screen
System.out.println("Pressure: "+pre+" Top Level: "+toplev+" Flow Rate: "+flo+" Bottom Level: "+botlev+" Temperature: "+temp);
//send output to DistillationColumn client
try
{
for(int i = 0; i <= 100; i++)
{
pre += 1;
toplev += 1;
flo += 1;
botlev += 2;
temp += 3;
output.println(pre+"|"+toplev+"|"+flo+"|"+botlev+"|"+temp);
Thread.sleep(500);
}
}
catch(InterruptedException e)
{
System.out.println("Error: "+e);
}
}
catch(NoSuchElementException ex)
{
finished = true;
}
}
}
catch(Exception ex)
{
System.out.println("Error: "+ex.toString());
}
//close the connection
try
{
incoming.close();
}
catch(Exception ex)
{
System.out.println("Error: "+ex.toString());
}
}
}
>...C program...
You don't use JNI to communicate to applications.You use it to communicate to a API which is encapusulated in a shared library.
And since you are using a socket I would guess that you are actually communicating that way.
First I would make real sure that the C application expects the doubles as binary representations rather than string representations. And if it is binary see if it can be convert to string. If it must be binary then continue reading.
IF AND ONLY IF, the native application runs on the same platform as the gui then it would probably be easier to send the java doubles to a native api to process them into bytes. All you do then is pack them into a structure and return the structure as an array of bytes.
If the native app doesn't run on the same OS then you have a lot of work in front of you. None of which will be helped by JNI.
You will need to figure out the byte format of the OS the C app is on. You will need to convert the double to an integer format. Then use byte and bit manipulation to create a float value that matches the OS format. And you have to reverse it when it comes back.
Hi there,
Thanks for your reply. Well my native application runs on the same platform as the GUI. Secondly I did not understand what exactly you ment by - " You don't use JNI to communicate to applications. You use it to communicate to a API which is encapusulated in a shared library."
Could you please elaborate it. I want to communicate to this C program because our client donot want to change his C program to java. The C program needs total 5 input values i.e of double or even float will do. Then it will do some processing and will return back some new set of values to the same variables. This C program is actually a Simulator so it will perform number of iterations and output of each iteration mush be sent back to the server. Again the nimber of iterations will depend upon the initial value sent to the C program and these iterations will continue until the system in C program converjes. Just because the JNI give us the facility to use the code written in other language that java we thought of using this technology. Well some more help from your side is awaited.
bye
And thanks once again
JNI talks to C code. So in JNI you would call a function named whose prototype is:
int otherGuysRoutine(double v1, double v2);
This is not java code it is C code. You (not the other guy) write code to call this and then compile it using a C compiler. This does not communicate to a running C application. Rather the C code is running in the java program in the same way that when you do a gui screen the gui screen java code talks to the OS.
And just to emphasis it again you must write C code to talk to the api and java.
The example code you provided was using sockets to talk to an application. The fact that the application is written in C is irrelevant. At least it is unless it tries to pass C floating numbers as bytes. Then as I said that is a problem.
There are a couple of points that, if you clarify them, might make it easier to help you.
1. The C code: Is it a program or a subroutine library?
2. You say the results of the C execution will be sent back to the server. What will send it back to the server?
o You want the C to return it to your GUI, which will send it back to the server?
o The C will send it back to the server?
3. What is your server? Java? Something else?
4. What is your communication method?
o Sockets?
o RMI?
Hi,
Here are the answers to your questions:
1. The C code is a program which does some iterations and returns back some floating point values.
2. The result of C output i want to get displayed on the GUI but these result will first be delivered to the server which inturn will give it to GUI client through Sockets.
3. I am using the Sockets as communication medium.
I hope that should be sufficient and I have already posted my server code ahead in my discussion.
Thanks in advance.
P.S: Waiting for your help.
OK.
o You have a server program.
o You have a java client program.
o You have a C program.
A client program will receive from the server some numbers.
o The client will pass the numbers to a C program.
o The C program will munch the numbers, then pass some results to your server.
The client program will get updated results from your server.
.....
As others have said earlier, JNI is NOT for making java communicate with a C program. (JNI is for making a java program talk to C SUBROUTINES, implemented as a shared library. The subroutines can be thought of - probably should be thought of - as extensions to the java language.)
If the model is as I have described it, then you want two programs, one java and one C, operating in separate process spaces, to communicate.
This can be relatively easy, or it can be hard, depending on exactly what you want to have happen on the client computer.
o If an instance of the C program should run when the java program has something to communicate, you can use Runtime.getRuntime.exec(...) to invoke the C program, passing it the input values to munch.
o If you want the C program sitting there all the time just waiting for input, then you have quite a bit of more work to do; My quick guess is that your best way to talk to the C program is via (more) sockets.
Hi There,
Thanks for all your valuable suggestions. Now you got the architecture of the project correctly. I have a GUI client from where I am getting some input numbers. These I want to pass to my C subroutine through server and get the new numbers from C subroutine and pass them back to the GUI client again through the server. As you have given me couple of options I think I will go for the first one:
o If an instance of the C program should run when the java program has something to communicate, you can use Runtime.getRuntime.exec(...) to invoke the C program, passing it the input values to munch.
Could you elaborate more on this option like what are the plus and minus of this option over the second and can you also suggest me that should I declare the native method in the server code itself or should I create entirely different class where I should create the native method and then call its implementation. I have already given my server code at my first request.
Thanks once again in advance.
I am desperately waiting for your valuable response.
Let me repeat that passing native floating point numbers from a C application via a socket is going to require a lot of java code. It would better if they were passed as strings.
Hi there,Well tanks for your help. I am going to pass the floating point values as string only to and from the C program. Thanks once again.
You are posting things that are confusing people - at least me:Is your C code going to be a subroutine, or is it going to be a program?
>You are posting things that are confusing people - at least me: I believe that was answered. It is a seperate application and the communication method is with sockets.
Hi there,
I am really sorry if i am confusing you. But frankly speaking I am totally new to this field(i.e software). This is my first project. I myself am confused when reading all such replys. I am really not sure what should I call the code which is written in C language a Subroutine or a Program(Since not a technocrat in IT). Well what I want to do is I am having some code in C program to which I should pass abt 5 floating point values(from my Distillation Column.). This column is displayed as gif image using JApplet. On this image there are about 5 circles, a click on each of these circles opens up a JOptionpane dialog box from where the user is allowed to input the floating point numbers(these are nothing but pressure or temperature or flow rate for the column). These number we have to send back to the C code which does some sort of programing and does some further calculations on these numbers and generates new floating point values. These generated values we intend to send back and we intend to display it over the gif image exactly above or below the circles. The number of iterations this C program will perform depends upon the value the user has inputted, the check for the convergence is done by the C program. Now our aim is to display each and every new set of value generated by this C code over the gif image. So the values will be continually changing over the image(this is anologous to have a for loop which continues for a fixed number of time, hence dont get confused with the for loop which we have used in the server program, its just a demo to show the bridge between Ckient GUI and the server is working fine) untill the C code is converged and will finally stop running. So at last only one set of value will be displayed on the image. Now since we wish to put this over the internet the proposed arichetecture for this project was to use the traditional Server Socket programming. Beleive me this whole technology is new to me. Hence I am having whole lot of problems. Well we were successful in building the bridge between the GUI client(which is the column gif image) and the above mentioned server. So my dear friend hope I have tried my level best to clear the confusion. So now can you please help me in building the bridge between the C code and the server. From my side when I was reading some books on JNI I thought that JNI would be the best solution for my problem. Now I know that there are several methods to send arguments to this C code. We can send the arguments as String, float, array(Being 5 floating point values). Ultimately only in C code some calulation will be done on these numbers so till then even if the numbers travel as String or some other data type I have no botherations. Because art the end we can always do what is called as type casting. I know that when we write native method we have to do a lot of work. The original C code which currently exists I definitely have to do a lot of changes in it. Like for example the data types are not called as usual in C program they are always precee with a "j". So friend please tell me whether my approach is correct or I should totally change my thinking. And if I am on write path then please guide me further.
Thanks a lot for all your valuable help till now.
Hoping for more help.
Bye
Hello,are you doing this on a Unix box? Have you ever experienced high CPU usage while running the Java app that have JNI in it?Andy
At least one reader has overlooked the fact that you have called your C code both "program", and "subroutine".
Between these two types of C code, there is a big difference in how you would go about communicating from java to that code.
So let us get down to some finer-grained questions:
Does the C code have a routine called "main"?
On what computer is your C code run?
Do you have the C code in a compiled form?
o A running program? (on a Windows computer, that's a file ending ".exe")
o A shared library? (On a Windows compter that's a file ending "dll")
If the C code isn't too large, you could post it, perhaps cutting out some of the number crunching.
At least one reader has overlooked the fact that you have called your C code both "program", and "subroutine".
Between these two types of C code, there is a big difference in how you would go about communicating from java to that code.
So let us get down to some finer-grained questions:
Does the C code have a routine called "main"?
On what computer is your C code run?
Do you have the C code in a compiled form?
o A running program? (on a Windows computer, that's a file ending ".exe")
o A shared library? (On a Windows compter that's a file ending "dll")
If the C code isn't too large, you could post it, perhaps cutting out some of the number crunching.
Hi there,
We are having MainWndProc() and not "main". Hencs it is not Console based but it is windows based. Well but we are ready to alter the C code so that we can go for JNI(ofcourse if that's the solution). Our C code runs on all machines(I hope you are not asking the operating system and if it it OS then it runs on Windows 2000). The C cod eis in compiled form and has .exe and not .dll.
I am really sorry that due to company privacy policy I cannot post the C code. So as I have made it clear the company is ready to alter the C code to fit the requirements.
Thanks
OK - we're getting somewhere. Your program IS a program - a Windows, GUI-based program - but your company is willing to change that if necessary.
You are planning to write another - java - GUI program that will
o take some values from a server on another computer.
o pass these values to the C program which will munch them.
o The C program will pass the munched values to the server.
Do you want or expect the C program GUI to be showing while the java-based client is running?
If not, then your organization will have to change the C code in one of two ways:
o Create a special command-line version that the java program can call via exec(), passing the values to be munched.
OR
o Create a subroutine library - a DLL - which your java program can call via JNI.
Which way to go?
o The batch program can be written so that it is platform independent.
o The DLL will probably be faster, because you aren't starting up another process every time you call for munching.
o Both exec calls and JNI have a learning curve, exec is easier.
o Your C program also does - I guess - communications with the server. I haven't done this before in a DLL, and maybe it's easy, but if I really wanted to use a DLL, then I might try to do ALL communications to the server from java.
Hi There,
Thanx a lot, now even I feel better and now I am also getting the track what exactly should be done. Well we dont want or expect the C program GUI to be showing while the java-based client is running. So we will go ahead for the option of changing the program. Now out of the two waye suggested by you the second one is faster but involve some or rather lot of learning work where as the first one is easier. Well could you please suggest me if we choose the second way that is creating a subrouting library - a DLL which our java program will call. Now here my question is can I declare the native method in my java server code? and can i call that method through the server itself once I receive the new values from the client? and how should I pass these new floating point values to my newly created C subrouting as a String or as Arrat or somting else because I want the C subrouting to return all of these 5 munched values back to my java server(Server code is ginev at the start of this discussion). So as far as my knowledge goes we cannot return at a time more that one value back(here I am not talking of using if else statements and writing number of return statements). And I too beleive that the communication should be done through the java server. So if you can guide me from here on like where should I look for more details for further study in the area of jni. And I would also request you to send me your contact e-mail so that in future if i need any help I can get in touch with you. I hope you dont have any reservations in forwarding your e-mail. By the way my e-mail is kvijay75@hotmail.com so you can send your id to me at this address.
Thanks a lot once again. Waiting for your reply.
Vijay
