# Bndtools Resolve vs Command line

**URL:** <https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559>\
**Category:** GENERAL\
**Created:** [April 12, 2026, 1:38pm UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559 "2026-04-12T13:38:29Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![rimmeraj](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/rimmeraj/32/251_2.png) [@rimmeraj](https://bnd.discourse.group/u/rimmeraj)\
**Post date:** [April 12, 2026, 1:38pm UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559/1 "2026-04-12T13:38:29Z")

</div>

Wondering what magic bndtools uses to get get it’s reolve of bndrun files so fast. In bndtools the resolve takes 15 seconds max on complex resolves, On the command line 2+ minutes. Is there some caching or flags I am missing?

---

<div class="post-metadata">

**Author:** ![chrisrueger](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/chrisrueger/32/18_2.png) [@chrisrueger](https://bnd.discourse.group/u/chrisrueger)\
**Post date:** [April 18, 2026, 9:27pm UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559/2 "2026-04-18T21:27:38Z")

</div>

Hard to tell from the outside. Could you share which [bnd resolve CLI command](https://bnd.bndtools.org/commands/resolve.html) you use?  
The docs mentions “bndrun files” (plural) at the top… so maybe CLI is processing multiple?

Are Eclipse bndtools version and bnd CLI version the same? (what’s the output of `bnd version` on CLI?)

---

<div class="post-metadata">

**Author:** ![rimmeraj](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/rimmeraj/32/251_2.png) [@rimmeraj](https://bnd.discourse.group/u/rimmeraj)\
**Post date:** [April 20, 2026, 11:04am UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559/3 "2026-04-20T11:04:13Z")

</div>

I am just using a little program. Versions are the same

var run = Bndrun.createBndrun(null,runFile);  
run.getModel().setRunBundles(new java.util.ArrayList())  
String res = null;  
try  
{  
res = run.resolve(true,false);  
}

10-15 seconds in eclipse  
2 minutes standalone

---

<div class="post-metadata">

**Author:** ![peterkir](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/peterkir/32/28_2.png) [@peterkir](https://bnd.discourse.group/u/peterkir)\
**Post date:** [June 11, 2026, 4:30am UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559/4 "2026-06-11T04:30:48Z")

</div>

## **Root Cause Analysis: Eclipse (10-15s) vs. Standalone (2 minutes)**

The performance gap is **not** caused by a bug or algorithmic difference in the resolver itself. It comes from two compounding differences in how repositories are initialized and how their indexes are loaded between the two environments.

### **1. Repository Index Already Loaded In-Memory (Eclipse)**

In Eclipse/Bndtools, the `Workspace` is a long-lived singleton that is created once when the IDE starts. All configured `OSGiRepository` (or other `Repository`) plugins are already initialized and their indexes are already parsed and cached **in-memory** as live Java objects.

When you call `run.resolve(...)` inside Eclipse, `BndrunResolveContext.init()` calls `loadRepositories()` → `getAllRepos()`, which retrieves already-initialized, in-memory repository objects from the shared workspace. The index data (the full OSGi resource/capability/requirement graph) is **already in RAM** and the `BridgeRepository` Promise is already resolved.

In standalone mode (`Bndrun.createBndrun(null, runFile)`), a **brand-new** `Workspace` is created via `Workspace.createStandaloneWorkspace(...)` and `ws.open()`. Every `OSGiRepository` plugin starts with `inited = false`. The very first call to `findProviders()` (during `resolver.resolve(rc)`) triggers `OSGiRepository.prepare()`, which:

- Creates a new `OSGiIndex`
- Calls `readIndexes(false)`, which downloads all index XMLs via `HttpClient`
- Parses potentially large OBR/R5 index XML files
- Builds the full `ResourcesRepository` and `BridgeRepository`

All this happens **synchronously** at resolve time (the Promise is awaited via `.getValue()` inside `getBridge()`), taking most of the 2 minutes.

### **2. HTTP-Level Index Cache Is Not Warm (Standalone)**

`HttpClient` defaults its URL cache to `Home.getUserHomeBnd("urlcache")` — a shared disk cache. However:

- The `OSGiIndex.download()` call uses `client.build().useCache(staleTime)` where `staleTime` defaults to `YEAR` (365 days). So once the HTTP cache is warm, subsequent standalone runs should be fast too.
- **The first run** (or any run after the cache expires or is cleared) must fetch index files from the network. For a remote OBR repository with a large XML index, this can easily add tens of seconds to minutes depending on the size and network latency.
- In Eclipse, the same `HttpClient` instance has been running for hours/days. Its URL cache is always warm for the index files, so it serves them from the local disk cache with an HTTP 304/UNMODIFIED response.

### **3. Plugin/Workspace Initialization Overhead (Standalone)**

`Workspace.createStandaloneWorkspace()` + `ws.open()` initializes the full plugin infrastructure from scratch:

- Loads and instantiates all `-plugin` entries from properties
- Initializes `HttpClient`, reads connection settings
- Creates `ResourceRepositoryImpl`, `CachedFileRepo`, etc.
- If `-standalone` points to remote repository URIs, `OSGiRepository.prepare()` is called for **each** one during `getPlugins(Repository.class)` (triggered by the `Prepare` interface and `initRepositories()`)

In Eclipse, the workspace is initialized **once** at IDE startup, amortized over all operations done during the session.

### **Summary Table**

| **Factor** | **Eclipse** | **Standalone** |
| --- | --- | --- |
| Workspace already initialized | ✅ Yes (live since IDE start) | ❌ No (created fresh per call) |
| Repositories initialized in memory | ✅ Yes | ❌ No (initialized on demand at resolve time) |
| Repository index XML parsed | ✅ Already done | ❌ Done during `resolve()` call |
| HTTP index cache state | ✅ Warm (Eclipse ran earlier) | ❌ Cold (first run), or warm after first run |
| OSGi index in-memory | ✅ `BridgeRepository` Promise already resolved | ❌ Promise resolved during resolve, blocking |

### **Mitigation**

If you need the standalone call to be consistently fast, you can:

1. **Reuse the `Workspace`** across multiple `Bndrun.resolve()` calls rather than recreating it each time — this amortizes the initialization cost.
2. **Ensure the HTTP URL cache is warm** before resolving (the `~/.bnd/urlcache/` directory). After the first standalone run the index files will be cached on disk and subsequent runs will be much faster.
3. Set `-offline: true` or `-gestalt: offline` in the bndrun file to prevent re-checking remote indexes (relies entirely on disk cache).
4. Use the `cache:` config attribute in `-standalone` or `-plugin.repo` to point the `OSGiRepository` cache to a fixed local directory that persists across JVM invocations.
5. Consider setting `max_stale` explicitly to a large value so the cached index is used without re-validation for longer.

---

<div class="post-metadata">

**Author:** ![ed123123](https://avatars.discourse-cdn.com/v4/letter/e/b9bd4f/32.png) [@ed123123](https://bnd.discourse.group/u/ed123123)\
**Post date:** [July 12, 2026, 2:52am UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559/5 "2026-07-12T02:52:17Z")

</div>

Very nice explanation, thank you @peterkir !

It sound like it would be nice to have a kind of bnd-server optional start mode for bnd CLI, allowing us to save time for those (probably rare) people who do not use bndtools (Eclipse) and only rely on a IntelliJ based IDE (like Community or OpenIDE ) and bnd-CLI for work with OSGi-bnd projects.

By the way, I prefer to avoid Eclipse, in favor of IntelliJ productivity, and I think it could be quite possible if bnd-CLI add this kind of improvements.

I remember reading some notes written by @pkriens remarking important design considerations taken into account when designing bnd-CLI interacting with any IDE.

It would be very nice to review such considerations (probably requirements) stated just from the beginning of the design of bnd-CLI and, at the same time take in considerations LSP and also what has been learning in Eclipse Bndtools in order to take such benefits extrapolated to Emacs and IntelliJ based IDEs or just bnd-CLI.

By the way, I am willing to work in LSP for .bnd files. Mi initial idea is to develop the LSP using OCaml programming language, but weather it should be write using Java-based framework in order to get relevant people invest time, improving it, for me it is not a problem. But if I am “solo”, I prefer to make the bnd-LSP in OCaml.

---

<div class="post-metadata">

**Author:** ![chrisrueger](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/chrisrueger/32/18_2.png) [@chrisrueger](https://bnd.discourse.group/u/chrisrueger)\
**Post date:** [July 12, 2026, 10:16am UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559/6 "2026-07-12T10:16:15Z")

</div>

> [@ed123123](#):
>
> it would be nice to have a kind of bnd-server optional start mode for bnd CLI

I few options come to mind which you could try:

- [shell [options] | bnd](https://bnd.bndtools.org/commands/shell.html) (_“The shell also supports bnd commands…”_): I haven’t used it myself but I think it was mentioned to me in the past somewhere for similar things

- bnd CLI commands: `bnd dev` and `bnd build -watch`

Those things above start a long running process which could fit your use case of doing expensive initialization work once.

---

<div class="post-metadata">

**Author:** ![ed123123](https://avatars.discourse-cdn.com/v4/letter/e/b9bd4f/32.png) [@ed123123](https://bnd.discourse.group/u/ed123123)\
**Post date:** [September 3, 2026, 8:15am UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559/7 "2026-09-03T08:15:48Z")

</div>

I tried `bnd build --watch` and emacs, and observed 2 important behavior when compilation fails:

1. If compilation fails, the corresponding error messages are not shown
2. If compilation fails, the old version of the .class file are not deleted

Combining the two, it seems to me, there is no chance to get any signal that compilation failed.

So, two questions:

1. Is there some Compilation Server Provider - Client (likewise Language Server Protocol - Client) useful to connect Emacs and `bnd build --watch` for get information about compilation and navigate the code where the error occurs?
2. There is a technique or best practice for use bnd build in order to avoid surprising behavior like old .class not deleted? [I will write more about it, but in a different thread]

Regards

Edgar

---

<div class="post-metadata">

**Author:** ![chrisrueger](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/chrisrueger/32/18_2.png) [@chrisrueger](https://bnd.discourse.group/u/chrisrueger)\
**Post date:** [September 4, 2026, 6:26am UTC](https://bnd.discourse.group/t/bndtools-resolve-vs-command-line/559/8 "2026-09-04T06:26:42Z")

</div>

> [@ed123123](#):
>
> 1. Is there some Compilation Server Provider - Client (likewise Language Server Protocol - Client) useful to connect Emacs and `bnd build --watch` for get information about compilation and navigate the code where the error occurs?

There were different discussions and initiatives but none of them made significant progress.

> <https://github.com/bndtools/bnd/issues/5833>
>
> The \[Language Server protocol\](https://langserver.org/) is used between a tool (…\_the client\_) and a language smartness provider (\_the server\_) to integrate features like auto complete, go to definition, find all references and alike into the tool.
> 
> Like discussed on \[EclipseCon2023\](https://www.eclipsecon.org/2023) BND instructions seem very well suited to be provided as a LSP so it can be used in an IDE agnostic way.
> 
> For Eclipse there is https://github.com/eclipse/lsp4e to easily integrate such servers.
> 
> FYI @maho7791 @juergen-albert @stbischof ...
> 
> @mickaelistria can you give some advice here how to best start using \[lsp4j\](https://github.com/eclipse-lsp4j/lsp4j)?

I talked with @timothyjward at OCX conference this year and I think there is still interest - but as usual it requires somebody having the requirement, time and monetary budget to drive this forward.

Besides that: `bnd build --watch` and `bnd dev` are more or less experimental proof of concept tools. They lack certain capabilities which LSP could provide. Both combined could work. We’ll see 🙂
