Passing a two-way object with jni4net (was: Ignore the missing class (s))

I am using jni4net to access Java code from a C # application and vice versa. jni4net uses reflection to generate the proxy code for the JNI code, so obviously one of the limitations is that your Java and C # code must be compiled to create the proxy.

Unfortunately, this can lead to a catch-22 problem. Consider:

C # class X uses Java Y class
Java class Y uses C # X class

None of them can be compiled, so a well-established solution is to take one of the classes (X or Y), break it into your bare signature and force it to compile, and then generate a proxy from the compiled skeleton. Then you can replace the divided class with the original and continue your fun journey.

This seems like an ugly approach to me, and I believe that there should be a better way. The obvious solution would be to tell the compiler (either C # or Java, it doesn't really matter) to ignore references to the missing class.

Do not ignore references to some missing class valid for C # or Java compilers? Is there a better way to do this (and no, I'm not open to considering sockets or anything of that nature, I need a real transition between .NET and Java)?

An example code was requested:

The jni4net transition code example code has been removed for clarity. IA and IB simple interfaces are also not included.

Java:

public class A implements IA { public void m1() { System.out.println("m1 called"); } public static void main (String args[]) { IB b = new B(); b.m2(new A()); } } 

FROM#:

 public class B : IB { public void m2(IA a) { a.m1(); A a2 = new A(); a2.m1(); } } 
+4
source share
2 answers

I decided to solve this problem myself. This is not related to my initial hunch, so I changed the name of this problem to better reflect the actual problem.

While the jni4net package has many useful examples, it seemed that there were no good ones showing the transfer of an object in both directions without any strange assembly of gymnastics (see the original statement of the problem). I figured out how to do this, and present the solution here along with the commands needed to build the result.

The easiest way to get this is to configure jni4net, as the instructions say, and delete all of this material in the new subdirectory of the examples directory that comes with the jni4net package.

C # code first:

Src / test / left.cs

 namespace test { using System; using net.sf.jni4net; using test; public class left : iright { public static void Main(String[] args) { left l = new left(); l.sendMeToRight(); } public left() { Console.WriteLine("left side constructed..."); } public void sendMeToRight() { BridgeSetup bridgeSetup = new BridgeSetup(); bridgeSetup.AddAllJarsClassPath("."); Bridge.CreateJVM(bridgeSetup); Bridge.RegisterAssembly(typeof(right).Assembly); Console.WriteLine("Sending myself to right."); right il = new right(this); il.announceMyself(); } public void announceMyself() { Console.WriteLine("Hello from the left side..."); } } } 

And now the Java code:

Src / test / iright.java

 package test; public interface iright { void announceMyself(); } 

Src / test / right.java

 package test; public class right implements iright { public right(iright f) { System.out.println("right side constructed... "); f.announceMyself(); } public void announceMyself() { System.out.println("Hello from the right side..."); } } 

And finally, the build script (I built it to run in cygwin and a very short time, so change it as needed.):

 @echo off rm -rf build mkdir build mkdir build\test copy ..\..\lib\*.* build echo Compile base classes. javac src/test/*.java mv src/test/*.class build/test echo Creating jar file. jar cvf build\lr.jar -C build test/iright.class -C build test/right.class rm build/test/*.class echo Generating proxies. ..\..\bin\proxygen.exe build\lr.jar -wd build echo Compiling derived proxy classes. javac -cp build\lr.jar;build\jni4net.j-0.8.0.0.jar build\jvm\test\iright_.java build\jvm\test\right_.java echo Packing compiled derived proxy classes. jar cvf build\lr.j4n.jar -C build\jvm test\__iright.class -C build\jvm test\iright_.class -C build\jvm test\right_.class echo Generating derived proxy DLL. cd build csc.exe /nologo /warn:0 /t:library /out:lr.j4n.dll /recurse:clr\*.cs /reference:"c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll" /reference:jni4net.n-0.8.0.0.dll echo Generating product executable. csc.exe /nologo /warn:0 /out:demo.exe /target:exe /reference:jni4net.n-0.8.0.0.dll /reference:lr.j4n.dll ..\src\test\left.cs 
+4
source

In C # 4, you can use the dynamic keyword when accessing a Java object. Did not try your script for sure. Some sample code will help.

edit for updated question
You have a circular dependency that one compiler will most likely complain about, not to mention two. Refactoring to something more similar to the following will help. Of course, this will probably not be so easy in your real code.

 // java public class A implements IA { public void m1() { System.out.println("m1 called"); } } public class MainClass { public static void main (String args[]) { IB b = new B(); b.m2(new A()); } } //C# public class B : IB { public void m2(IA a) { a.m1(); A a2 = new A(); a2.m1(); } } 
0
source

All Articles