Call Java from .NET Project: Anatomy of a Shared Memory Bridge

JNBridgePro — the fastest, easiest way to bridge Java and .NET in production. Generate proxies in minutes, call Java from C# (or C# from Java) with native syntax — trusted by enterprises worldwide. Learn more · Download free trial

What We’re Building

In this post we’ll break down the anatomy of a simple interop project where a .NET application calls into a Java class using JNBridgePro with shared memory. If you need to call Java from a .NET project, understanding these moving parts is essential.

The goal is to make the moving parts visible:

  • how a proxy connects the .NET and Java worlds,
  • what files live on each side,
  • other considerations for shared memory setups.

Switching this project to TCP (plus added considerations like SSL, IP/class whitelisting, and Java-side startup) will be covered in a separate post: Changing to TCP: Configuration, SSL, Whitelisting & Startup.

Project Layout for Java .NET Interop

Here’s the directory structure of a demo project (BridgeDemo). At a glance, you can see two main areas:

  • .NET project (BridgeDemo) – the C# application, configuration file, and runtime DLLs.
  • Java side (Java Side) – the original Java class and supporting JARs and properties.

.NET Side: Calling Java with JNBridgePro Shared Memory

On the .NET side, the project is built around referenced assemblies, supporting DLLs, and the App.config that defines how it connects to the Java side.

Referenced Assemblies

  • bridgeDemo.dll – the proxy assembly that exposes the Java class to .NET.
  • JNBShare.dll – the core bridge library required for all JNBridge communication.

Both are added under References in Visual Studio and have Copy Local = True, ensuring they’re automatically placed in the output folder when you build. This way, BridgeDemo.exe can find them at runtime without extra configuration.

Supporting DLLs

  • JNBSharedMem_x86.dll / JNBSharedMem_x64.dll – required only when using the Shared Memory transport.
  • jnbauth_x86.dll / jnbauth_x64.dll – used internally by the bridge for authentication and setup.

These supporting DLLs are not referenced in the project. They simply need to be present in the same directory as BridgeDemo.exe.

App.config

At runtime, BridgeDemo.exe uses this configuration to tell JNBridge how to locate and load the Java side. Below is a sample configuration for the Shared Memory transport:

<jnbridge>
  <dotNetToJavaConfig
    scheme="sharedmem"
    jvm64="C:\Program Files\Java\jdk-25\bin\server\jvm.dll"
    jnbcore="C:\Projects\BridgeDemo\Java Side\jnbcore.jar"
    bcel="C:\Projects\BridgeDemo\Java Side\SharedMemory\bcel-6.10.0.jar"
    classpath="C:\Projects\BridgeDemo\Java Side;C:\Projects\BridgeDemo\Java Side\javaToCall.jar;"
  />
</jnbridge>
  • scheme – transport type (sharedmem or tcp).
  • jvm64 – points to the 64-bit JVM to load (jvm32 used if needed).
  • jnbcore – path to jnbcore.jar, which contains the bridge runtime.
  • bcel – only required when using Shared Memory; omitted for TCP.
  • classpath – tells JNBridge where to find your Java classes or JARs (the Java Side folder in this project).

The classpath section determines whether the .NET side connects to a Java package directory containing .class files, a JAR, or both if listed together. Learn more about how JNBridgePro connects .NET and Java.

Java Side

The Java side hosts the actual code and bridge runtime that the .NET process connects to. It generally includes core/supporting JARs, the Java code or JAR, and a properties file defining how the JVM bridge runs.

Core and Supporting JARs

  • jnbcore.jar – always required; contains the bridge runtime and handles all communication.
  • bcel-6.10.0.jar – only needed for Shared Memory transport.

Java Code or Packaged JAR

You may have either of the following, depending on how your build is structured:

  • A package directory (for example, BridgeDemo/) with .class files.
  • Or a JAR archive (such as BridgeDemo.jar) containing the compiled classes.

Which of these is used depends on the classpath specified in the .NET project’s App.config.

Java-Side Properties File

This file (for example, javaSide.properties) controls how the JVM runs the bridge. Typical entries include:

javaSide.serverType=sharedmem
javaSide.timeout=10000
javaSide.port=8085
javaSide.useClassWhiteList=false
javaSide.classWhiteListFile=./classWhiteList.txt
javaSide.useSSL=false

Considerations for Shared Memory Setups

Shared Memory provides the fastest .NET↔Java communication since both run in the same process, but it requires correct architecture alignment and file placement.

The JVM architecture must match your .NET build target:

  • 64-bit .NET → use 64-bit jvm.dll.
  • 32-bit .NET → use 32-bit jvm.dll. (Note: running x86 shared memory in JNBridgePro v12 may hit a hidden runtime dependency.)

Supporting DLLs must also match:

  • JNBSharedMem_x86.dll / JNBSharedMem_x64.dll
  • jnbauth_x86.dll / jnbauth_x64.dll

You can omit the unused architecture’s DLLs (for example, keep only the x64 set for a 64-bit-only build). If the app may run in both modes (for example, AnyCPU), include all four — JNBridge will automatically load the correct pair at runtime.

All bridge DLLs (JNBShare.dll, JNBSharedMem_x*.dll, jnbauth_x*.dll) must reside in the same directory as your executable.

Handling ClassNotFoundException and NoClassDefFoundError

These errors during shared-memory startup usually come from missing permissions or classloader issues in older JVMs.

  • Permissions – Ensure the user running the app has Read & Execute, List Folder Contents, and Read access to all Java class and JAR folders (jnbcore.jar, bcel-6.x.x.jar, and any app JARs). Missing access prevents the JVM from loading classes, especially under ASP.NET.
  • Classloader conflicts (Java 8 and earlier) – If permissions are correct but errors persist, move the affected .jar from the classpath to the boot classpath using -Xbootclasspath/p: and remove it from the regular classpath.
<jnbridge>
  <dotNetToJavaConfig
    scheme="sharedmem"
    jvm64="C:\Program Files\Java\jdk-25\bin\server\jvm.dll"
    jnbcore="C:\Projects\BridgeDemo\Java Side\jnbcore.jar"
    bcel="C:\Projects\BridgeDemo\Java Side\SharedMemory\bcel-6.10.0.jar"
    classpath="C:\Projects\BridgeDemo\Java Side;"
    jvmOptions.0="-Xbootclasspath/p:C:\Projects\BridgeDemo\Java Side\javaToCall.jar"
  />
</jnbridge>

In this example, javaToCall.jar was removed from the classpath and added to the boot classpath, allowing the JVM to load it earlier and resolve the conflict. (The -Xbootclasspath/p: option works only through Java 8 and was removed in Java 9+.)

Ready to build your own Java .NET interop project? Download JNBridgePro and visit the developer center for more resources.


Related Articles

Related JNBridgePro guides: