# Session Management

Inrupt’s Java Client Libraries provide a [Session](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/auth/Session.html) interface to handle session objects. In multi-user contexts, multiple sessions in a single application must be managed to ensure that one user’s session is not used by another user.

The following content provides some recommendations for managing sessions in multi-user applications.

### Session Scope

#### Avoid Application-Scoped Sessions

For multi-user applications, the general guidance is to <mark style="color:red;">**avoid**</mark> making a session scoped to the entire application. That is, when using dependency injection framework such as [Spring](https://spring.io/) or [JakartaEE](https://jakarta.ee/):

* Do <mark style="color:red;">**NOT**</mark> use **`@ApplicationScope`**, **`@ApplicationScoped`**, or equivalent scope.
* Do <mark style="color:red;">**NOT**</mark> use **`@Singleton`** or equivalent scope.

#### Use Request-Scoped Sessions

For applications where a session is used by different components, instantiating an independent session inside each component introduces unnecessary overhead. Instead, in cases where these applications also use dependency injection framework such as [Spring](https://spring.io/) or [JakartaEE](https://jakarta.ee/), consider using request scopes:

* **`@RequestScope`** in Spring,
* **`@RequestScoped`** in JakartaEE, or
* the equivalent annotation in your framework.

{% hint style="danger" %}
For the session object:

* Do <mark style="color:red;">**NOT**</mark> use **`@ApplicationScope`**, **`@ApplicationScoped`**, or equivalent.
* Do <mark style="color:red;">**NOT**</mark> use **`@Singleton`** or equivalent.
  {% endhint %}

<pre class="language-java"><code class="lang-java">import com.inrupt.client.auth.Session;
import com.inrupt.client.openid.OpenIdSession;
<strong>import jakarta.enterprise.context.RequestScoped;
</strong>import jakarta.inject.Inject;
// ...

<strong>@RequestScoped
</strong>public class SessionManager {
    private Session session;

    @Inject
    JsonWebToken jwt

    Session getSession() {
        if (session == null) {
            session = OpenIdSession.ofIdToken(jwt.getRawToken());
        }
        return session;
    }
}
</code></pre>

With request scoped session, the Java runtime automatically removes references to that session at the end of a request.

### Application Scoped Clients

{% hint style="warning" %}
Disambiguation

The following refers to the client object (i.e. [SolidClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidClient.html), [SolidSyncClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidSyncClient.html)) and not the session object ([Session](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/auth/Session.html)).

Do <mark style="color:red;">**NOT**</mark> use application/singleton scope (or equivalents) with sessions.
{% endhint %}

For the client object (i.e. [SolidClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidClient.html), [SolidSyncClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidSyncClient.html)),

When possible, use application/singleton scope for clients.

<pre class="language-java"><code class="lang-java">import com.inrupt.client.solid.SolidSyncClient;
<strong>import jakarta.enterprise.context.ApplicationScoped;
</strong>// ...

<strong>@ApplicationScoped
</strong>public class ClientManager {
    private SolidSyncClient client = SolidSyncClient.getClient();

    @Produces
    SolidSyncClient getClient() {
        return client;
    }
}
</code></pre>

Then, a Web component (e.g., **`DataEndpoint`** in the following code block) of this application can use the application-scoped client and the request-scoped session in the following manner:

```java
@ApplicationScoped
@Path("/data")
public class DataEndpoint {

    @Inject
    SolidSyncClient solidClient;     // ClientManager class is ApplicationScoped. See above.

    @Inject
    SessionManager sessionMgr;       // SessionManager class is RequestScoped. See above.

    @GET
    public DataObject fetch() {
        var client = solidClient.session(sessionMgr.getSession());
        var uri = URI.create(...);
        try (var data = client.read(uri, DataObject.class)) {
            return data;
        }
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.inrupt.com/sdk/java-sdk/authentication/session-management.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
