- name
- sdk-replacement
- description
- Invoke this skill to replace Neo Java Web API with SAP Cloud SDK. Detects neo-java-web-api or scp-neo dependencies in pom.xml, or com.sap.cloud.*/com.sap.core.connectivity.* imports. Required foundation skill - invoke after jakarta-java25-migration.
- disable-model-invocation
- false
- allowed-tools
- Read, Edit, Write, Bash, Grep, Glob
# Replace Neo Java Web API with SAP Cloud SDK
Replace the Neo-specific Java Web API with SAP Cloud SDK for Cloud Foundry compatibility.
## Purpose
The Neo Java Web API (`com.sap.cloud:neo-java-web-api`) is not available in Cloud Foundry. This skill replaces it with SAP Cloud SDK dependencies that provide equivalent functionality for the CF environment.
## Detection
This skill applies if any of these patterns are found:
### In pom.xml
```xml
<dependency>
<groupId>com.sap.cloud</groupId>
<artifactId>neo-java-web-api</artifactId>
</dependency>
<!-- OR -->
<dependency>
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>scp-neo</artifactId>
</dependency>
```
### In Java source files
```java
import com.sap.cloud.account.*;
import com.sap.core.connectivity.api.*;
import com.sap.security.um.user.*;
```
## Prerequisites
> **Working directory:** This skill must run inside the `-cf-migration` copy of your app, created by `jakarta-java25-migration` or `neo-to-cf-migration-orchestrator`. If your current directory does not end in `-cf-migration`, switch to it before proceeding.
Before invoking this skill, ensure you have invoked:
1. **jakarta-java25-migration** - `Use the jakarta-java25-migration skill`
- Migrates to Java 25 and Jakarta EE 10
- REQUIRED before this skill
## Transformation Steps
### Step 1: Remove Neo SDK Dependencies
Remove from `pom.xml`:
```xml
<!-- REMOVE this dependency -->
<dependency>
<groupId>com.sap.cloud</groupId>
<artifactId>neo-java-web-api</artifactId>
<version>${neo.version}</version>
<scope>provided</scope>
</dependency>
<!-- ALSO REMOVE if present -->
<dependency>
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>scp-neo</artifactId>
<version>${sdk.version}</version>
</dependency>
```
### Step 2: Add SAP Cloud SDK BOM Dependencies
Add to `<dependencyManagement>` section:
```xml
<dependencyManagement>
<dependencies>
<!-- CF Tomcat BOM - provides servlet container and runtime -->
<dependency>
<groupId>com.sap.cloud.sjb.cf</groupId>
<artifactId>cf-tomcat-bom</artifactId>
<version>${cf-tomcat-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SAP Cloud SDK BOM - provides SDK modules -->
<dependency>
<groupId>com.sap.cloud.sdk</groupId>
<artifactId>sdk-modules-bom</artifactId>
<version>${sdk-modules-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
### Step 3: Resolve and Add Version Properties
> **Do NOT write a version number from memory.** SAP BOM versions drift quickly,
> and any literal you put here is *guaranteed* to be stale within months. The
> reference scenarios in this repo and earlier drafts of this skill have
> shipped numbers like `2.22.0` and `5.14.0` that no longer round-trip in the
> SAP `build-snapshots` artifactory; the migration build dies with
> `Non-resolvable import POM: ... cf-tomcat-bom:pom:<X> (absent)` followed by
> a cascade of `'dependencies.dependency.version' is missing` errors for
> every artifact the BOM was supposed to manage.
>
> Resolve the latest released version *now*, every time, before writing it
> into `pom.xml`.
Run a one-line lookup against Maven Central's public search API for each BOM
the skill manages. It hits a stable, no-auth endpoint, sorts release versions
(those with a hyphen-suffixed qualifier like `-RC` or `-SNAPSHOT` are filtered
out by the regex), and prints exactly one line — the latest version string:
```bash
latest_version () {
curl -fsS --max-time 10 \
"https://search.maven.org/solrsearch/select?q=g:$1+AND+a:$2&core=gav&rows=20&wt=json" \
| jq -r '.response.docs | map(select(.v | test("^[0-9]+(\\.[0-9]+)*$")))
| sort_by(-.timestamp) | .[0].v'
}
CF_TOMCAT_BOM_VERSION=$(latest_version com.sap.cloud.sjb.cf cf-tomcat-bom)
SDK_MODULES_BOM_VERSION=$(latest_version com.sap.cloud.sdk sdk-modules-bom)
echo "Resolved: cf-tomcat-bom=${CF_TOMCAT_BOM_VERSION}, sdk-modules-bom=${SDK_MODULES_BOM_VERSION}"
```
If either lookup returns empty or `curl` exits non-zero (network issue,
registry change), **stop**: report the error to the user. Do **not** fall
back to a number from training data.
Then write the resolved values into `<properties>` of the migrated `pom.xml`:
```xml
<properties>
<!-- Both versions are resolved at migration time, not pinned. -->
<cf-tomcat-bom-version>RESOLVED_CF_TOMCAT_BOM_VERSION</cf-tomcat-bom-version>
<sdk-modules-bom-version>RESOLVED_SDK_MODULES_BOM_VERSION</sdk-modules-bom-version>
</properties>
```
Substitute the literal values from the lookup above for the two `RESOLVED_*`
placeholders. After writing, sanity-check by running
`mvn help:effective-pom -q -DforceStdout | head` — if the BOM imports cleanly
the version is good.
> **Source of truth:** the resolver queries
> [search.maven.org](https://search.maven.org/) — the same registry as
> [cf-tomcat-bom](https://mvnrepository.com/artifact/com.sap.cloud.sjb.cf/cf-tomcat-bom)
> and [sdk-modules-bom](https://mvnrepository.com/artifact/com.sap.cloud.sdk/sdk-modules-bom)
> on mvnrepository.com. If you need to confirm the result by eye, those URLs
> are the canonical browser-friendly views.
### Step 4: Add SCP-CF and Security Dependencies
Add to `<dependencies>` section:
```xml
<dependencies>
<!-- SAP Cloud SDK for Cloud Foundry -->
<dependency>
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>scp-cf</artifactId>
</dependency>
<!-- SAP Cloud Security Java API (required for XSUAA integration) -->
<dependency>
<groupId>com.sap.cloud.security</groupId>
<artifactId>java-api</artifactId>
</dependency>
<!-- Servlet API (provided by buildpack) -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
</dependencies>
```
> **Note:** The `jakarta.servlet-api` does not need an explicit `<scope>provided</scope>` as this is inherited from the BOM.
### Step 5: Detect existing JSON/logging/HTTP conventions before adding dependencies
Before adding any new dependencies, scan the project to avoid introducing duplicate libraries:
```bash
# JSON libraries
grep -E "fasterxml\.jackson|com\.google\.code\.gson|org\.json|jakarta\.json" pom.xml
grep -rl "ObjectMapper\|new Gson()\|new JSONObject\|JsonbBuilder\|Json\.create" --include="*.java" src/main/java/ 2>/dev/null | head -5
# HTTP client libraries
grep -E "httpclient|httpclient5|okhttp|java\.net\.http" pom.xml
# Logging
grep -E "slf4j|logback|log4j" pom.xml
```
**Rule:** If a library is found — reuse it. Only add a new dependency if nothing is found.
| Library type | Default if nothing found |
|---|---|
| JSON | `jakarta.json` (JSON-P via `parsson`) — already in `cf-tomcat-bom`, no extra entry needed |
| HTTP | SAP Cloud SDK `HttpClientAccessor` — already present after this skill |
| Logging | `slf4j` + `logback` — already in `cf-tomcat-bom` |
### Step 6: Add Additional Dependencies (as needed)
Depending on what Neo APIs you were using, add these dependencies:
```xml
<!-- If using OpenCMIS (Document Management) -->
<dependency>
<groupId>org.apache.chemistry.opencmis</groupId>
<artifactId>chemistry-opencmis-client-impl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.chemistry.opencmis</groupId>
<artifactId>chemistry-opencmis-client-api</artifactId>
</dependency>
<!-- If using Mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
</dependency>
<!-- If using JSP -->
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- If using EL -->
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- If using WebSocket -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<scope>provided</scope>
</dependency>
```
### Step 7: Migrate SAPUI5 ResourceServlet (Conditional)
In Neo, the platform-provided `com.sap.ui5.resource.ResourceServlet` served SAPUI5 libraries at `/resources/*`. This servlet class does **not exist** in Cloud Foundry. If HTML files reference SAPUI5 via a relative `resources/sap-ui-core.js` path, the page will load but render **blank** because the UI5 library returns 404.
#### Detect
```bash
# Check for ResourceServlet in web.xml
grep -r "ResourceServlet\|com.sap.ui5.resource" --include="*.xml" src/main/webapp/
# Check for relative SAPUI5 loading in HTML files
grep -r 'src="resources/sap-ui-core.js"' --include="*.html" src/main/webapp/
```
If either returns results, apply the fixes below.
#### 6a: Remove ResourceServlet from web.xml
Remove the servlet declaration and mapping:
```xml
<!-- REMOVE: Neo-specific SAPUI5 resource servlet -->
<servlet>
<servlet-name>ResourceServlet</servlet-name>
<servlet-class>com.sap.ui5.resource.ResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ResourceServlet</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
```
#### 6b: Update HTML Files to Use SAPUI5 CDN
Replace the relative path with the SAPUI5 CDN URL in **all** HTML files.
> **CRITICAL:** The old CDN domain `sapui5.hana.ondemand.com` no longer serves older SAPUI5 versions (pre-1.71) and may be fully retired. Always use the current CDN domain `ui5.sap.com`.
**Before:**
```html
<script id="sap-ui-bootstrap" type="text/javascript"
src="resources/sap-ui-core.js"
...></script>
```
**After:**
```html
<script id="sap-ui-bootstrap" type="text/javascript"
src="https://ui5.sap.com/resources/sap-ui-core.js"
...></script>
```
**Bulk fix (relative paths):**
```bash
grep -rl 'src="resources/sap-ui-core.js"' --include="*.html" src/main/webapp/ | \
xargs sed -i 's|src="resources/sap-ui-core.js"|src="https://ui5.sap.com/resources/sap-ui-core.js"|g'
```
**Bulk fix (old CDN domain):**
```bash
grep -rl 'sapui5.hana.ondemand.com' --include="*.html" src/main/webapp/ | \
xargs sed -i 's|sapui5.hana.ondemand.com|ui5.sap.com|g'
```
> **Note:** If the application requires a specific SAPUI5 version, pin it in the URL: `https://ui5.sap.com/1.120.0/resources/sap-ui-core.js`. Older versions (pre-1.71) are no longer available on the CDN — if the app pins an old version, update to a supported LTS version (e.g., 1.108.x or 1.120.x).
#### 6c: Update Deprecated SAPUI5 Themes (Conditional)
The `sap_bluecrystal` theme was removed in SAPUI5 1.40+. If your application references it, it will fail to load the theme CSS, causing either a broken layout or a blank page.
**Detect:**
```bash
grep -r "sap_bluecrystal" --include="*.html" --include="*.json" src/main/webapp/
```
**Fix:** Replace with `sap_fiori_3` (Quartz Light) or `sap_horizon` (latest):
```bash
# Update in HTML files
Auf GitHub ansehen