How to call Function from an C# dll in Java? - java

i have a SAP-DLL to enable communication between a Programming interface and the SAP Programm.
I have following example Code for c# in combination with the dll-File:
var loggerService = LoggerService.GetLoggerService("FileLogger");
var itasProxy = SapProxyFactory.CreateSapProxy(SapSystem.Example, loggerService, "Example_User", StringExtension.CreateSecureString("Example_Password"));
var funcResult = sapProxy.SearchSapAddress(clientNo);
if (funcResult.Successfull)
{
funcResult.ReturnValue = withFormatting
? AddressFormatter.SplitStreetHouseNo(funcResult.ReturnValue)
: funcResult.ReturnValue;
}
Now i want the same functionality to be transferred to java. I have absolutely no clue how to do that. I tried the following with Loggerservice as a starter, but it doesn't work:
public class SAPConnector {
public static void main(String[] args) {
// TODO Auto-generated method stub
connectSAP();
}
public void connectSAP()
{
System.load("C://Temp//SapConnector.dll");
Object loggerService = getLoggerService("FileLogger");
}
public native Object getLoggerService(String lcLogger);
}
i just need some kind of information how to call the Functions from the dll or an example how to transfer the C# Code to working Code in Java.
Greetings,
Kevin

DLL is Microsoft format. Java is cross-platform, thus can't acknowledge anything operating-system specific, such as DLL.
One way around that is to use JNI (Java Native Interface), but that's usually not a good solution, as it makes your program platform-dependent.
Instead, I would look for a JAR from SAP, that provides a similar interface.
Maybe something along SAP JCO.
You can see some actual code examples using JCO here, and some technical information on step-by-step download and configure here.

Related

How to send from JAVA String(path of file) to C?

i want to send from java some paths to C.
For example i have a folder that have 4 subfoldes... From java i read the length of them from the code below and it returns me 4.
public static int GetLength(){File file = new File("C:\\Registrations");
File[] files = file.listFiles(new FileFilter(){
public boolean accept(File f) {
return f.isDirectory(); }});
return files.length;} }
Now with a thread i start to call the function that connect with C
public Start(){ Thread listeningThread = new Thread(new Runnable(){
public void run(){
new Match(GetDBNumber()); } });
listeningThread.start();}
So far all good. Now from MATCH(int x) class i want to call a C code and every time give the path of the Main folder each time
*PSEUDOCODE* public class Match {
public Match( int len){
System.out.println("subfolders : "+len);
for (i=0; i<len; i++)
{ //Some way call C programm (like an exe)
//with the first,second,third,fourth path
}
.... }
The C code that will recieve the path will be look like that...
int main() {
FILE *fp = fopen(FilePATH, "r");
......
......
return 0; }
I try with ProcessBuilder but i cant send the path every time with this way...
ProcessBuilder p = new ProcessBuilder();
//receive.exe is the exe that Codeblocks create after built the C code
p.command("C:\\Users\\PC\\Documents\\NetBeansProjects\\TEST\\C\\recieve.exe");
try {
p.start();
} catch (Exception e) {System.out.println("Error");
}
As stated by Eric Fitzsimmons,
you will need to use JNI to pass a String value from Java to C.
The C part will need to be in a dll that is available to the Java program.
Wikipedia has a JNI article
Oracle has an in-depth JNI write-up
Edit Concerning JNI.
If you want to send a value between Java and C,
there are only a few ways to do it.
JNI. As stated, Java Native Interface is built for this. This seems to be the best solution.
Use an external Data store. Write something to a data store (maybe a file or a database) on one side and read it on the other side (sides being Java and C).
Write a stand-alone C program that writes to standard out. Launch that program from within Java. Read what was written in java. This is not a great idea.
Depends on a lot of variables. I'll assume that you are building the C code and can change how things are passed, so...
Easiest to hardest:
Pass it in as a command line parameter (only works once per C file execution)
Write/update a text file on your hard drive that the C program can watch
Use TCP/IP and send messages over a pre-designated socket
Build as a shared library or DLL and Use JNI to call the C functions
If you were doing this professionally and this was just the beginning of a larger development effort you'd be wise to look into more professional tooling:
a message bus (Apache has one called ActiveMQ) is designed to do exactly what you are trying to do (and so much more)
a shared cache (Hazlecast can connect Java to C++ and nearly everything else and share data freely)
A shared table in a database that both languages can access.
These are much higher initial investment in time (otherwise free) but they have innumerable features that you could continue to take advantage of as your system grows.
Use jni (Java native interfaces) Make a c++ .dll file and you can easily pass information between both languages.
Good example/explanation for using jni:
https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

c# And/Or vb.net equivalent of apache commons Validate

In Java, if Apache Commons Lang jar is in the classpath, we can do one line Validates, like
Validate.isTrue(someBoolean, "This should be true");
In effect the above is the same as:
if (! someBoolean) {
throw new RuntimeException("This should be true");
}
Is there something in the .net world that will do the same?
I know I have seen code somewhere that did something similar but I can't remember where or the systax.
Any help is much appreciated.
You can, of course, write your own:
public static class Validate
{
public static void IsTrue(bool value)
{
if (!value) throw new InvalidOperationException(message)
}
}
Also, in C# or VB you can use code contracts:
Contract.Requires(someBoolean, "This should be true")
This requires downloading the code contracts extension from the Visual Studio extensions site. You can turn on code contracts and have them verified at compile time, and it allows specifying fairly arbitrary contract conditions.

How to pass an object from Java to JavaScript using Rhino

I am working on a Java program where an object needs to have user-customization behavior for one function. I am implementing this using Mozilla Rhino, JavaScript and Java.
I cannot figure out how to take the already instantiated object and pass it to a pre-written script.
I have looked through many tutorials on Rhino, and none have given an example like this. Any advice or links would be greatly appreciated.
Thank you for your time.
This answer to another question passes an object, data, from Java to Rhino Javascript.
I have no idea whether or not it works (well I suppose it does). Here are the relevant parts:
public static class data {
Double value = 1.0d;
}
ScriptEngine engine = new ScriptEngineManager().getEngineByName ("rhino");
data data = new data();
Context.enter().getWrapFactory().setJavaPrimitiveWrap(false);
engine.eval("function test(data) { return data.get('value1') + 5;};");
System.out.println("Result:" + ((Invocable)engine).invokeFunction("test", data));
(I didn't know about that setJavaPrimitiveWrap(), here is some WrapFactory Javadoc.)

Using Windows API call in Java using "native"

I've tried to solve this issue by referring possible duplicates but none of them seem to be helpful.
Here's a code that I'm using to call Win API methods in Java to get current Windows User Name, and a native Windows MessageBox, but I'm getting UnsatisfiedLinkError that says that my code is unable to locate the native method I'm trying to call.
public class TestNative
{
public static void main(String[] args)
{
long[] buffer= { 128 };
StringBuffer username = new StringBuffer((int)buffer[0]);
GetUserNameA(username,buffer);
System.out.println("Current User : "+username);
MessageBoxA(0,"UserName : "+username,"Box from Java",0);
}
/** #dll.import("ADVAPI32") */
static native void GetUserNameA(StringBuffer username,long[] buffer);
/** #dll.import("USER32") */
private static native int MessageBoxA(int h,String txt,String title,int style);
}
What can be my possible (relatively simple) solution to call native Windows methods in Java. I realize that it will kill the very reason of Java being a cross-platform language, but I need to work on a project for Windows, to be developed in Java.
Thanks.
Update
As David Heffernan suggested, I've tried changing the method signature of MessageBox to MessageBoxA, but still it's not working.
I would guess it's related to the signatures not matching completely.
The GetUserName function takes two parameters: a LPTSTR and a LPDWORD. Java will likely not handle the StringBuffer acting as a TCHAR array for you.
Also, why bother using the Windows API for this? Java can probably get the user's logon name (quick google says: System.getProperty("user.name")), and Swing can make a message box (even one that looks like a Windows one).
Have you tried https://github.com/twall/jna. I have heard good things and its supposed to make jni that bit easier with many conveniences and simplifications.
Do you have a -Djava.library.path VM arg set with the path to your DLL's? Alternatively, you can have it in your system PATH.
The error is because there is no MessageBox. You presumably mean MessageBoxA.

How can I call a Java object/function from Oracle Forms 6i?

I am working on a legacy project that is using Oracle Forms 6i (yes, I know its old) to call C++ functions from a PLL library.
Now we need to use Java instead of C++, therefore we need to call Java (Object/Class/Method) from Oracle Forms.
I know its a challenging subject, but I would be really happy if someone could provide a simple example that does the following:
Invoking a method from the Java class, passing a int variable (within PL/SQL)
Printing the returned value in the Canvas that executed the Function.
A basic example, perhaps a Hello World would be ideal.
I know some PL/SQL, but I am not a Oracle Forms developer; please bear with me.
If this is not possible, could you point me to some other alternatives?
Well, after an intensive lookup through the internet I came across a very good resource (in Spanish though): Elias blog about Oracle Forms and Java
I use:
Oracle Forms 6i
JDK 1.6
With this I managed to create the hello world example:
Configure PATH environment variables:
C:\PATH_TO_JAVA\Java\jdk1.6.0\bin;
C:\PATH_TO_JAVA\Java\jdk1.6.0\jre\bin;
C:\PATH_TO_JAVA\Java\jdk1.6.0\jre\bin\client;
Ex: PATH_TO_JAVA = C:\Program Files
Add to CLASSPATH
FORMS_HOME\TOOLS\common60\JAVA\IMPORTER.JAR (In my case FORMS_HOME was C:\orant)
PATH_TO_YOUR_JAR\NAME_OF_JAR.jar
Create Java Program
Create with your IDE a simple java program, following is mine:
public class HiWorld{
private String hi="Hello World!";
public String getHi(){
return this.hi;
}
public String getMultiply(int a, int b){
return ""+a*b;
}
public static void main(String args[]){
HiWorld hm = new HiWorld();
System.out.println(hm.getHi());
System.out.println(hm.getMultiply(5,10));
}
}
Export it to Jar file (Path has to be the one you put in CLASSPATH environment variable.
Import the classes to Forms
Create a new project in Oracle Forms and also create a Canvas, in the canvas use a Text and a Button. The name of the button: TEXT_HI_WORLD.
Following click on the Menu: Program > Import Java Classes
If everything went Ok then there will be a new window that will show you the package where the Class is, you extend it until there is the HiWorld class. Import it.
In Program Unit now there will be two files:
HIWORLD (Specification)
HIWORLD (Body)
This are files generated automatically and needed to use the class.
Then go back to the canvas, right click on the Button and select the Thrigger WHEN-BUTTON-PRESSED, the programming of this will be:
DECLARE
v_wb ORA_JAVA.JOBJECT;
v_hi VARCHAR2(20);
BEGIN
v_wb := hiworld.new();
v_hi:= hiworld.getHi(v_wb);
:TEXT_HI_WORLD := v_hi
END;
Now execute the program and click on the button! :)
Hope this helps Java programmers with no much of knowledge on Forms to integrate with legacy systems! :D
I've done this before, and with a simple class this should work, but when you try to develop something more complicated, I recommend extend from the VBean class, you can find the library within oracle's forms installation folders (frmall.jar).
// el programa corregido.
public class HolaMundo {
private String hi= "Hey World!!!";
public String GetHi(){
return this.hi;
}
public static void main(String args[]){
HolaMundo hm = new HolaMundo();
System.out.println(hm.GetHi());
}
}

Categories

Resources