How to Use Java Libraries in .NET Core and .NET 8/9 Applications
Table of Contents
- Why Use Java Libraries in .NET Core?
- The Challenge: JVM and CLR Are Different Worlds
- Your Options for Accessing Java Libraries from .NET Core
- Option 1: Find a .NET Alternative or Rewrite
- Option 2: Wrap the Java Library in a REST Service
- Option 3: In-Process Access with JNBridgePro
- Step-by-Step: Calling a Java Library from .NET Core with JNBridgePro
- Popular Java Libraries Developers Access from .NET
- Considerations Specific to .NET Core/.NET 8/9
- FAQ
The .NET ecosystem is powerful, but some capabilities only exist in Java libraries. Whether it’s Apache PDFBox for PDF manipulation, Apache Tika for content extraction, Stanford NLP for natural language processing, or Lucene for full-text search — sometimes the best tool for the job was written in Java.
This guide shows you how to use Java libraries in .NET Core and modern .NET (8/9) applications without rewriting them, wrapping them in microservices, or compromising on performance.
Why Use Java Libraries in .NET Core?
Developers working in .NET Core frequently need Java libraries for several reasons:
- No equivalent .NET library exists — Java’s 25+ year ecosystem includes mature, battle-tested libraries with no .NET counterpart of equal quality
- Rewriting is too expensive — Porting a complex Java library to C# could take months or years, and you’d lose community updates and bug fixes
- Organizational requirements — A Java team built internal libraries that the .NET team now needs to consume
- Migration in progress — You’re moving from Java to .NET Core incrementally and need access to Java code during the transition
- Regulatory or certification — A specific certified Java implementation must be used (common in finance and healthcare)
The Challenge: JVM and CLR Are Different Worlds
Java libraries run on the Java Virtual Machine (JVM). .NET Core applications run on the Common Language Runtime (CLR). These are completely separate runtime environments with different type systems, memory management, and execution models.
You can’t simply reference a .jar file from a C# project the way you’d reference a .dll. The two runtimes don’t share a binary format, object model, or memory space. Bridging them requires either a network boundary (out-of-process) or a runtime bridge (in-process).
Your Options for Accessing Java Libraries from .NET Core
There are three practical approaches, each with different trade-offs:
Option 1: Find a .NET Alternative or Rewrite
Before bridging runtimes, check whether a .NET-native alternative exists:
| Java Library | .NET Alternative | Parity |
|---|---|---|
| Apache PDFBox | iTextSharp, PDFsharp, QuestPDF | Partial — different APIs, some missing features |
| Apache Tika | No direct equivalent | Low — Tika’s format coverage is unmatched |
| Apache Lucene | Lucene.NET (port) | High — but lags behind Java Lucene versions |
| Stanford NLP | ML.NET, SpaCy (.NET bindings) | Low — different models and capabilities |
| Bouncy Castle | Bouncy Castle for .NET | High — maintained .NET port exists |
| Apache POI | NPOI (port), ClosedXML | Medium — some features missing |
When this works: The .NET alternative is feature-complete for your needs and actively maintained.
When it doesn’t: You need specific Java APIs, exact behavioral compatibility, or the .NET port is abandoned or incomplete.
Option 2: Wrap the Java Library in a REST Service
Package the Java library in a Spring Boot (or similar) web application, expose the functionality you need as REST endpoints, and call them from .NET Core using HttpClient.
// .NET Core calling a Java library via REST
var client = new HttpClient();
var response = await client.PostAsync(
"http://java-service:8080/api/extract-text",
new ByteArrayContent(pdfBytes)
);
string extractedText = await response.Content.ReadAsStringAsync();When this works: You need the Java library infrequently (a few calls per request), your team already runs microservices, and you can accept the operational overhead of a separate Java service.
When it doesn’t: You need to make many calls per operation (latency adds up), you need access to complex object graphs (serialization becomes a nightmare), or you don’t want to deploy and monitor a separate service.
Option 3: In-Process Access with JNBridgePro
JNBridgePro runs the JVM inside your .NET Core process, generating C# proxy classes that map directly to Java classes. From your .NET Core code, Java objects look and feel like native .NET objects.
// .NET Core accessing Apache PDFBox via JNBridgePro
using com.aspose.pdf; // Java classes appear as .NET namespaces
PDDocument doc = PDDocument.load(new java.io.File("document.pdf"));
PDFTextStripper stripper = new PDFTextStripper();
string text = stripper.getText(doc);
doc.close();
// Direct method calls — no HTTP, no serializationWhen this works: You need frequent access to Java APIs, complex object interactions, low latency, or you’re using the Java library as a core part of your application’s functionality.
Advantages over REST wrapping:
- No separate service to deploy — the Java library runs inside your .NET Core app
- Microsecond latency — shared-memory communication vs. millisecond HTTP round-trips
- Full API access — call any public Java class, method, or field, not just what you’ve wrapped in endpoints
- Complex object graphs — pass and receive Java objects directly without serialization
- Exception propagation — Java exceptions become .NET exceptions with full stack traces
Step-by-Step: Calling a Java Library from .NET Core with JNBridgePro
Step 1: Install JNBridgePro
Download JNBridgePro and install it. The package includes the proxy generation tool, runtime libraries, and documentation.
Step 2: Generate Proxy Classes
Use JNBridgePro’s proxy generation tool to create .NET proxy classes from the Java library’s JAR file. Point the tool at the JAR (and any dependencies), select the classes you need, and generate a .NET assembly containing the proxy classes.
The generated proxies mirror the Java API exactly — same class names, method signatures, and inheritance hierarchy, translated to .NET conventions.
Step 3: Reference Proxies in Your .NET Core Project
Add the generated proxy assembly and JNBridgePro runtime DLLs to your .NET Core project. Configure the bridge in your application’s startup:
// Configure JNBridgePro in .NET Core
DotNetSide.init();
// Now Java classes are available as .NET typesStep 4: Call Java APIs Like Native .NET Code
Use the Java library’s classes directly in C#. JNBridgePro handles all type marshaling, memory management, and cross-runtime communication transparently.
Step 5: Choose Transport Mode
JNBridgePro offers two transport modes:
- Shared memory — JVM runs in the same process. Lowest latency, simplest deployment. Best for most scenarios.
- TCP — JVM runs in a separate process or on a different machine. Useful for isolation or when the Java code requires a different OS. See our TCP configuration guide.
For detailed setup instructions, see the JNBridgePro Developer Center.
Popular Java Libraries Developers Access from .NET
Based on common use cases in enterprise environments:
Document Processing
- Apache PDFBox — PDF creation, manipulation, text extraction
- Apache POI — Excel, Word, PowerPoint file processing
- Apache Tika — Content detection and extraction for 1,000+ file formats
- iText (Java edition) — Advanced PDF generation and digital signatures
Search and NLP
- Apache Lucene — Full-text search engine library
- Apache Solr client — Solr search platform integration
- Stanford CoreNLP — Natural language processing, entity recognition, sentiment analysis
- OpenNLP — Machine learning-based NLP toolkit
Enterprise Integration
- JMS client libraries — IBM MQ, ActiveMQ, RabbitMQ JMS clients (also see JMS Adapter for BizTalk)
- JDBC drivers — Access databases with Java-only drivers
- Apache Kafka client — Native Kafka producer/consumer APIs
Security and Cryptography
- Bouncy Castle (Java) — Comprehensive cryptography library
- Keycloak client — Identity and access management
- SAML/OAuth libraries — Java-specific identity provider integrations
Considerations Specific to .NET Core/.NET 8/9
Cross-Platform Deployment
.NET Core runs on Windows, Linux, and macOS. When using Java libraries via JNBridgePro, ensure a compatible JRE/JDK is available on the target platform. JNBridgePro supports cross-platform deployment — the same proxy assemblies work on any OS where both .NET Core and a JVM are present.
Dependency Injection and Hosting
JNBridgePro integrates with .NET Core’s dependency injection container. Register Java services in Startup.cs or Program.cs and inject them like any other .NET service:
// Register Java-backed services in .NET Core DI
builder.Services.AddSingleton<IPdfProcessor, JnBridgePdfProcessor>();Docker and Containerization
When containerizing a .NET Core application that uses Java libraries, your Docker image needs both the .NET runtime and a JRE. A multi-stage build keeps the image lean:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
# Add JRE
RUN apt-get update && apt-get install -y default-jre-headless
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]Get Started with Java Libraries in .NET
Ready to use Java libraries in your .NET applications? Download a free evaluation of JNBridgePro to start calling Java libraries from .NET Core with native syntax — no REST wrappers, no microservices overhead. Contact the JNBridge team for help with your specific integration scenario.
.NET Core vs .NET Framework
If you’re migrating from .NET Framework to .NET Core, existing JNBridgePro integrations carry over. The proxy classes and runtime are compatible with both. Check the system requirements for specific version support.
FAQ
Can .NET Core use Java JAR files directly?
No. .NET Core cannot directly reference or load Java JAR files — they use incompatible binary formats (Java bytecode vs. .NET CIL). You need either a runtime bridge like JNBridgePro to access Java classes in-process, or a network-based approach (REST, gRPC) to access Java functionality as a service.
What Java versions work with .NET Core integration?
JNBridgePro supports Java 8 through the latest LTS releases (Java 21+). The Java library you’re accessing must be compatible with a supported JDK version. Most enterprise Java libraries support Java 8+ for backward compatibility.
Does using Java libraries in .NET Core affect performance?
With in-process bridging (JNBridgePro), the performance overhead per method call is microseconds — negligible for most applications. The Java library itself runs at native JVM speed. The main consideration is JVM memory allocation — plan your container or process memory to accommodate both the CLR and JVM heaps.
Can I use Java libraries in ASP.NET Core web applications?
Yes. JNBridgePro works with ASP.NET Core, including Razor Pages, MVC, Web API, and Minimal API projects. Java library calls can be made from controllers, services, middleware, or background services. Thread safety follows the Java library’s own thread-safety guarantees.
Is IKVM an alternative for using Java libraries in .NET Core?
IKVM translates Java bytecode to .NET CIL, allowing Java code to run directly on the CLR. This works for simple, self-contained libraries but has limitations with complex Java code that depends on JVM internals, dynamic class loading, or specific JVM behaviors. JNBridgePro runs an actual JVM, so all Java APIs and behaviors work as documented.
Related Articles
More Java-.NET integration guides:
- How to Call Java from C# — Complete Guide
- Java .NET Integration: All Options Compared
- Anatomy of a Shared Memory Bridge
- How to Call C# from Java
