JvmBridge 26.10.23.4023

dotnet add package JvmBridge --version 26.10.23.4023
                    
NuGet\Install-Package JvmBridge -Version 26.10.23.4023
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="JvmBridge" Version="26.10.23.4023" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="JvmBridge" Version="26.10.23.4023" />
                    
Directory.Packages.props
<PackageReference Include="JvmBridge" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add JvmBridge --version 26.10.23.4023
                    
#r "nuget: JvmBridge, 26.10.23.4023"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package JvmBridge@26.10.23.4023
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=JvmBridge&version=26.10.23.4023
                    
Install as a Cake Addin
#tool nuget:?package=JvmBridge&version=26.10.23.4023
                    
Install as a Cake Tool

JvmBridge

CI License

Write JVM agents in C#. Generate the native bindings. Test the actual binaries.

JvmBridge combines generated JNI/JVMTI declarations, explicit Java reference ownership, and NativeAOT agent entry-point generation in one NuGet package. It works with ordinary Java applications and provides a standalone JVM-hosting API for .NET applications.

JvmBridge is published on NuGet, with companion packages: JvmBridge.Testing for xUnit tests, JvmBridge.Templates for a dotnet new agent template and JvmBridge.Logging for Microsoft.Extensions.Logging adapters. To start without writing a project file, run dotnet new install JvmBridge.Templates, then dotnet new jvmbridge-agent -n MyAgent.

A native agent in a few lines

Create a .NET 10 class library and reference JvmBridge:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <JvmBridgeAgent>true</JvmBridgeAgent>
    <PublishAot>true</PublishAot>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="JvmBridge" Version="<version>" />
  </ItemGroup>
</Project>

dotnet add package JvmBridge writes this line with the latest version from nuget.org; pin the one you test against. PublishAot is explicit because the SDK decides on NativeAOT while it evaluates the project, before the package's build assets can act on JvmBridgeAgent, so the package cannot imply it. Leaving it out fails the build with JVMB006; without that check dotnet publish would succeed and produce only managed assemblies, and no native library.

using JvmBridge.Agents;
using JvmBridge.Runtime;

public sealed class MyAgent : JavaAgent
{
    public override void OnLoad(AgentContext context)
    {
        context.Log("loaded with options: " + context.Options);
    }

    public override void OnVmInit(AgentContext context, JavaEnvironment environment)
    {
        using JavaLocalReference text = environment.NewString("Hello from C#!");
        context.Log(environment.GetString(text.Handle));
    }
}

No attribute or manually exported entry point is required. The generator finds the single concrete JavaAgent subclass and emits Agent_OnLoad, Agent_OnAttach, and Agent_OnUnload into your assembly. Override Configure to request capabilities before events are installed. OnAttach runs after callbacks are active, so it can immediately retransform existing classes. Abstract agent base classes are allowed; ambiguous or invalid agents produce compiler errors. context.Log writes to standard error without Console, which needs libicu to initialize.

Publish for the JVM process's operating system and architecture:

dotnet publish -c Release -r linux-arm64
java -agentpath:/absolute/path/MyAgent.so=hello -jar application.jar

Windows uses .dll; macOS uses .dylib; Linux uses .so. Native publishing requires the platform's C/C++ toolchain. The resulting library includes its .NET runtime; Java users do not need to install .NET. To load an agent through JAVA_TOOL_OPTIONS or into a running JVM, see Loading and attaching. A Linux agent needs the glibc of the machine that published it or newer; publish against .NET's sysroot for one that loads on glibc 2.17 and later, see Publishing for Linux.

On Unix HotSpot, use the JDK's signal-chaining library when hosting both runtimes in one process. For a typical Linux JDK:

LD_PRELOAD="$JAVA_HOME/lib/libjsig.so" java -agentpath:/absolute/path/MyAgent.so -jar application.jar

Locations differ across distributions and Java versions; Java 8 commonly places the library beneath jre/lib/<architecture>. macOS uses DYLD_INSERT_LIBRARIES with libjsig.dylib. The test runner discovers the correct library. Do not inject HotSpot's library into OpenJ9.

Capabilities

  • Generated native API: JNI/JVMTI types, constants, function-table entries, and callback signatures from pinned OpenJDK headers. C# raw declarations live in JvmBridge.Native and preserve native identifiers.
  • Runtime helpers: JVM creation, thread attachment, UTF-16 string conversion, modified UTF-8 names/options, checked field access, constructor and typed method calls, native registration, and owned local/global references.
  • Agent lifecycle: startup and late attachment, VM initialization/death, class preparation, copied JVMTI class/member metadata, capability negotiation, and retransformation.
  • Class files and patches: a read-only class-file model with named opcodes and instruction matchers, an editor whose edits keep every constant index and code offset, a writer and code builder for helper classes without byte literals, and declarative ClassPatches (redirects, constants, replaced constructions, removed fluent calls, added getters, setters and invokers, access flags, matchers, conditions on a method's code and Before/After method advice) with results a test can assert on, all without a JVM.
  • Helper classes: written in Java (JavaSource, compiled with javac against the application's jars or stub sources, with an optional pinned JDK download for machines that have none) or in C# ([JavaClass] and [JavaMethod]), in the bootstrap loader or the application's own.
  • Events and JVM state: thread, class-load, exception, method, garbage-collection and monitor events with capability negotiation, thread and stack wrappers, and class redefinition.
  • Java interop: arrays, exception throwing, monitors and local frames, [JavaMethod] with arrays, and typed proxies for the classes of a jar.
  • Logging and options: levels, a replaceable sink, an ILogger adapter and a parsed option string.
  • Testing: JvmBridge.Testing supplies checksum-pinned JDKs and Maven artifacts, javac and java runners, published-agent lookup, class-file assertions, disassembly snapshots, patches applied across a jar, and a link check of helpers against real classes.
  • Delivery and tooling: -agentpath, JAVA_TOOL_OPTIONS, the Attach API and java -javaagent with a jar from the jvmbridge command, which also disassembles classes and previews an agent's patches without a JVM.
  • One package: the runtime, source generator, and MSBuild integration ship together. Consumers do not need Clang or header files.
  • Real validation: CI publishes the example against the packed NuGet package and loads it into each available pinned JVM.

Documentation

Compatibility

The manifest tracks every NativeAOT target in scope and every Java major from 8 through 26, with HotSpot and OpenJ9 inventories. Agents also run on Java 6 and 7 from the same build when JavaRelease is 6 or 7; CI runs that on linux-x64 with Zulu 6 and 7, including glibc 2.12 (see Java 6 and 7). Archive availability varies by version and architecture. Mobile targets and platforms without a suitable JVM are explicitly experimental or unavailable.

See the generated compatibility inventory. It shows available downloads, not a blanket support claim. The matching commit's CI reports show which native builds and runtime tests actually passed. Historical patch releases are not exhaustively tested. JVM agent support does not follow automatically from .NET target support.

Examples

  • HelloAgent: emits a Java 8-compatible native callback helper in C#, registers native methods, preserves Unicode across threads/global references, transforms fixture method bodies, and supports late attachment.
  • LegacyAgent: one build for Java 6 to 26 (JavaRelease 6): a constant patch, a redirect to a C# helper and to a typed Java helper in the application's loader, replaced constructions, a removed fluent call, advice with a hook compiled from Java, events, and a thread attached from .NET.
  • JavaHost: creates a JVM from an explicit native-library path, invokes Java, handles exceptions, and demonstrates ownership.

See automation setup and agent instructions. Original code is MIT licensed; see upstream notices for header provenance.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on JvmBridge:

Package Downloads
JvmBridge.Testing

Test helpers for JvmBridge agents on xUnit v3: checksum-pinned JDKs, javac and java runners, published-agent lookup, and class-file assertions.

JvmBridge.Logging

Microsoft.Extensions.Logging adapters for JvmBridge agents: an ILogger that writes to the agent's log, and a redirect of the agent's log into an ILogger.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
26.10.23.4023 0 10/23/2026
26.10.23.3501 0 10/23/2026
26.10.23.2995 0 10/23/2026
26.10.23.2515 0 10/23/2026
26.10.23.2374 0 10/23/2026
26.10.22.7463 35 10/22/2026
26.10.22.5110 60 10/22/2026
26.10.22.4562 56 10/22/2026
26.10.22.4199 54 10/22/2026
26.10.22.3403 48 10/22/2026
26.10.22.3284 48 10/22/2026
26.10.22.2987 38 10/22/2026
26.10.22.2593 52 10/22/2026
26.10.22.2272 67 10/22/2026
26.10.22.2187 37 10/22/2026
26.10.22.2063 43 10/22/2026
26.10.22.1909 40 10/22/2026
26.10.22.1596 57 10/22/2026
26.10.22.1508 49 10/22/2026
26.10.19.3777 105 10/19/2026
Loading failed

- feat(samples): ✨ used an invoker, conditions and target checks in the legacy agent (8cdc466)
- feat(testing): ✨ pinned Maven artifacts, patched whole jars and link-checked helpers (4b7219c)
- feat(patching): ✨ checked that helpers declare what patches call in them (b38d61f)
- feat(patching): ✨ applied patches on conditions over a method's code (e8beff2)
- feat(patching): ✨ added getters, setters and invokers for private members (8a0ab3c)