# Using JPL from Spring Boot

**URL:** <https://swi-prolog.discourse.group/t/using-jpl-from-spring-boot/9083>\
**Category:** General\
**Created:** [June 29, 2025, 8:46pm UTC](https://swi-prolog.discourse.group/t/using-jpl-from-spring-boot/9083 "2025-06-29T20:46:17Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nspan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/nspan/32/3326_2.png) [@nspan](https://swi-prolog.discourse.group/u/nspan)\
**Post date:** [June 29, 2025, 8:46pm UTC](https://swi-prolog.discourse.group/t/using-jpl-from-spring-boot/9083/1 "2025-06-29T20:46:17Z")

</div>

I have a project where I load and unload different user files using a Java service that communicates with SWI-Prolog using JPL.  
In a typical service request the user wants to load a prolog file, then assert several facts and finally make a query. When the user finishes our service retracts the facts and unloads the file. However, we find that in the next service handling (serviced after the previous one has concluded) the file is still loaded and pollutes the query result.

Can you help to resolve this?

What is the cause?

Thank you

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 30, 2025, 7:20am UTC](https://swi-prolog.discourse.group/t/using-jpl-from-spring-boot/9083/2 "2025-06-30T07:20:52Z")

</div>

Without details it is hard to tell. Different requests ending up on different threads might be a problem.

That said, if for each query you want to populate Prolog with a program and data, solve that and remove everything you might end up better without JPL, assembling a file, start Prolog, collect the result and be done.

An alternative approach is using `in_temporary_module/3` from library(modules). It is a little fragile in the sense that you nicely have to obey its limitations or may end up with a crash. It does provide a means to quickly run a query on a temporarily loaded program without leaving traces. It is used by SWISH for isolating queries. SWISH also uses a dedicated thread for each query.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 1, 2025, 7:11am UTC](https://swi-prolog.discourse.group/t/using-jpl-from-spring-boot/9083/4 "2025-07-01T07:11:14Z")

</div>

> [@anon95304481](#):
>
> Isn’t this in principle a “worker”, as found in JavaScript.  
> Except maybe that it is less isolated. The temporary  
> modules can use shared libraries?

AFAIK, a worker is a complete instance of the language. A temporary module is merely a Prolog module that can import other modules and you can add clauses to it. Notably no other module may depend on it, i.e., no other module may import from a temporary module. When the goal of in\_temporary\_module/3 completes, no code may be accessing it. As a result, we can safely discard it.

A cleaner solution would be proper reference counting and GC for predicates and modules. That requires a lot of changes though. So, this is a quick-and-dirty solution to create a temporary isolated space for executing a query on data that is assembled for that query only and can be discarded afterwards. SWISH needed this. The isolation is one-way: the temporary module can use anything, bit nothing outside it can use the temporary module. The limitation is only partially enforced, which makes the thing fragile. Violating this restriction will lead to memory corruption.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 1, 2025, 9:32am UTC](https://swi-prolog.discourse.group/t/using-jpl-from-spring-boot/9083/6 "2025-07-01T09:32:22Z")

</div>

> [@anon95304481](#):
>
> [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) has a already an Engine abstraction, but does it also have a Knowledgebase abstraction. I have no clue.

Well, there have been a lot of posts and answers hinting it does not. It might actually be quite feasible to implement it. When the system was converted from single threaded to multi-threaded, all previously global variables were split into three structures:

- Local data (`LD` in the source) (holding the thread specific data)
- Global data (`GD` in the source) (shared data)
- “Code data”. This concerns some data structures that are initialised at startup and never modified afterwards. They were kept separate because there is no need to think about synchronizing access. C23 might allow us to compute this at compile time and store it away as `const` data.

So, GD is basically your knowledge base. The abstraction is probably not 100%, but close. As said, actually exploiting this is probably still quite a bit of work. If some project with a need and resources to implement this I’m happy to consider.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 1, 2025, 5:38pm UTC](https://swi-prolog.discourse.group/t/using-jpl-from-spring-boot/9083/8 "2025-07-01T17:38:42Z")

</div>

The point of my reply is that the “knowledge base” is accessed though a pointer to a struct everywhere. In theory you could create multiple instances of it and add a pointer from the `LD` thread/engine data to the knowledge base it uses. The required changes could be fairly limited.
