> This page is for Applications Protection.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.humansecurity.com/llms.txt.

# Upgrading

The upgrade process differs slightly depending on which version you're upgrading from.

#### Upgrading from SDK \< v4.x

Two things changed in v4.x:

* `isVerified()` is deprecated. Use `isRequestLowScore()` instead for the same check. This is optional and mainly useful for logging to indicate whether the request score was below the blocking threshold.
* `isHandledResponse()` is new and returns `true` when HUMAN already wrote the response (block page or first-party), meaning you **cannot** continue to `filterChain.doFilter`

To account for these, update your code accordingly:

#### Replace \`isVerified\` with \`isHandledResponse()\`

**`Before (< v4.x)`**

```java title="Before (< v4.x)" {2-3}
PXContext ctx = enforcer.pxVerify(req, new HttpServletResponseWrapper(resp));
if (ctx != null && ctx.isVerified()) {
    filterChain.doFilter(servletRequest, servletResponse);
}
```

**`After (>= v4.x) {6}`**

```java title="After (>= v4.x) {6}"
PXContext ctx = enforcer.pxVerify(req, new HttpServletResponseWrapper(resp));
// isHandledResponse() returns true when HUMAN already wrote the response:
//   - Request was blocked, OR
//   - Request was handled by first-party mechanism
// In both cases, do NOT forward to your application.
if (ctx != null && ctx.isHandledResponse()) {
    // HUMAN already handled the response - do NOT forward
    return;
}
filterChain.doFilter(servletRequest, servletResponse);
```

#### Optional: Add logging to indicate why the response was handled

```java {8-14}
PXContext ctx = enforcer.pxVerify(req, new HttpServletResponseWrapper(resp));
// isHandledResponse() returns true when HUMAN already wrote the response:
//   - Request was blocked, OR
//   - Request was handled by first-party mechanism
// In both cases, do NOT forward to your application.
if (ctx != null && ctx.isHandledResponse()) {
    // HUMAN already handled the response - do NOT forward
    // Optional: log why the response was handled
    if (ctx.isFirstPartyRequest()) {
          System.out.println("Handled by first-party mechanism");
    }
    if (!ctx.isRequestLowScore()) {
          System.out.println("Blocked request");
    }
    return;
}
filterChain.doFilter(servletRequest, servletResponse);
```

#### Update the builder syntax

Finally, the old `new PXConfiguration.Builder()` was replaced by Lombok's `PXConfiguration.builder()` and should be replaced accordingly:

**`Before (< v4.x)`**

```java title="Before (< v4.x)" {1}
PXConfiguration config = new PXConfiguration.Builder()
        .appId("<APP_ID>")
        .build();
```

**`After (>= v4.x)`**

```java title="After (>= v4.x)" {1}
PXConfiguration config = PXConfiguration.builder()
        .appId("<APP_ID>")
        .build();
```

#### Upgrading from SDK > v4.x

If you're already using an SDK version greater than 4.0, you don't need any code changes to upgrade. Simply follow these steps:

1. Run `mvn versions:display-dependency-updates`.
2. Update the version in your `pom.xml` or `build.gradle` file.
3. Rebuild.

#### Migrating to Jakarta EE (Spring Boot 3+)

Starting with SDK v6.17.0, Jakarta EE support is available as a separate Maven artifact. Use this path when upgrading to Spring Boot 3.x, Tomcat 10+, or any stack that uses the `jakarta.servlet` namespace.

#### Replace the SDK dependency

Remove `perimeterx-sdk` and add `perimeterx-sdk-jakarta` at the same version:

**`Maven`**

```xml title="Maven"
<!-- Before: Java EE / javax.servlet -->
<dependency>
   <groupId>com.perimeterx</groupId>
   <artifactId>perimeterx-sdk</artifactId>
   <version>${VERSION}</version>
</dependency>

<!-- After: Jakarta EE / jakarta.servlet -->
<dependency>
   <groupId>com.perimeterx</groupId>
   <artifactId>perimeterx-sdk-jakarta</artifactId>
   <version>${VERSION}</version>
</dependency>
```

**`Gradle`**

```groovy title="Gradle"
// Before
implementation 'com.perimeterx:perimeterx-sdk:${VERSION}'

// After
implementation 'com.perimeterx:perimeterx-sdk-jakarta:${VERSION}'
```

#### Update servlet imports

In your filter and any other code that references the servlet API, replace `javax.servlet` with `jakarta.servlet`:

**`Before (javax)`**

```java title="Before (javax)"
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
```

**`After (jakarta)`**

```java title="After (jakarta)"
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
```

The HUMAN Enforcer API (`com.perimeterx.*`) and filter logic remain unchanged.

#### Verify JDK and runtime requirements

Ensure your environment meets Jakarta EE requirements:

* **JDK 17 or higher** (required for `perimeterx-sdk-jakarta`)
* **Tomcat 10+** or another servlet container that implements Jakarta Servlet 6
* **Spring Boot 3.x** if you use Spring Boot

Configuration options and `PXConfiguration` settings are identical between both artifacts. See [Configuration](/applications/java/configuration) for details.