Skip to main content

tomee-runtime

Invoke this skill to configure TomEE container for EJB applications. Detects @Stateless, @Singleton, @EJB annotations, javax.ejb/jakarta.ejb imports, or neo-javaee7-wp-api dependency. Use instead of Tomcat for EJB support.

Informações da origem

Repositório
SAP-samples/btp-neo-java-app-migration
Última atividade na origem
29 de julho de 2026 às 13:26
Idioma detectado do SKILL.md
inglês
Estrelas
6
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
2 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
tomee-runtime
description
Invoke this skill to configure TomEE container for EJB applications. Detects @Stateless, @Singleton, @EJB annotations, javax.ejb/jakarta.ejb imports, or neo-javaee7-wp-api dependency. Use instead of Tomcat for EJB support.
disable-model-invocation
false
allowed-tools
Read, Edit, Write, Bash, Grep, Glob
# TomEE Runtime Configure TomEE container for JavaEE/EJB applications in Cloud Foundry. ## Purpose Migrate Neo applications using TomEE runtime (with EJB support) to Cloud Foundry's TomEE 10 container instead of Tomcat. ## Detection This skill applies if any of these patterns are found: ### In pom.xml ```xml <dependency> <groupId>com.sap.cloud</groupId> <artifactId>neo-javaee7-wp-api</artifactId> </dependency> ``` ### In Java source files ```java import javax.ejb.Stateless; import javax.ejb.Singleton; import javax.ejb.EJB; import javax.ejb.Schedule; @Stateless public class MyService { } @Singleton public class MySingleton { } ``` ### In web.xml or deployment descriptors ```xml <!-- EJB references --> <ejb-local-ref> <ejb-ref-name>ejb/MyService</ejb-ref-name> <local>com.example.MyService</local> </ejb-local-ref> ``` ## 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 Jakarta EE 10 - REQUIRED before this skill > **Note:** TomEE is an alternative to the Tomcat migration path. Choose TomEE if your application uses EJB features. ## Transformation Steps ### Step 1: Replace Neo Dependencies **Before (Neo):** ```xml <dependency> <groupId>com.sap.cloud</groupId> <artifactId>neo-javaee7-wp-api</artifactId> <version>${neo.version}</version> <scope>provided</scope> </dependency> ``` **After (Cloud Foundry TomEE):** See [assets/pom-cf-tomee.xml](assets/pom-cf-tomee.xml) for a complete template. Key changes: ```xml <dependencyManagement> <dependencies> <!-- CF TomEE BOM instead of cf-tomcat-bom --> <dependency> <groupId>com.sap.cloud.sjb.cf</groupId> <artifactId>cf-tomee-bom</artifactId> <version>${cf-tomee-bom-version}</version> <type>pom</type> <scope>import</scope> </dependency> <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> <properties> <!-- Resolve via sdk-replacement Step 3 (substitute `cf-tomee-bom` for `cf-tomcat-bom`). --> <cf-tomee-bom-version>RESOLVED_CF_TOMEE_BOM_VERSION</cf-tomee-bom-version> <sdk-modules-bom-version>RESOLVED_SDK_MODULES_BOM_VERSION</sdk-modules-bom-version> <jakarta.persistence-api-version>3.2.0</jakarta.persistence-api-version> </properties> <dependencies> <dependency> <groupId>com.sap.cloud.sdk.cloudplatform</groupId> <artifactId>scp-cf</artifactId> </dependency> <!-- Jakarta EE API provided by TomEE --> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>10.0.0</version> <scope>provided</scope> </dependency> </dependencies> ``` ### Step 2: Migrate EJB Annotations **Before (Java EE 7):** ```java import javax.ejb.Stateless; import javax.ejb.EJB; import javax.ejb.Schedule; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.annotation.PostConstruct; @Stateless public class MyBusinessService { @EJB private OtherService otherService; public String doWork() { return otherService.process(); } } @Singleton @Startup public class ApplicationInitializer { @PostConstruct public void init() { System.out.println("Application started"); } @Schedule(hour = "*", minute = "*/5", persistent = false) public void scheduledTask() { System.out.println("Running scheduled task"); } } ``` **After (Jakarta EE 10):** ```java import jakarta.ejb.Stateless; import jakarta.ejb.EJB; import jakarta.ejb.Schedule; import jakarta.ejb.Singleton; import jakarta.ejb.Startup; import jakarta.annotation.PostConstruct; @Stateless public class MyBusinessService { @EJB private OtherService otherService; public String doWork() { return otherService.process(); } } @Singleton @Startup public class ApplicationInitializer { @PostConstruct public void init() { System.out.println("Application started"); } @Schedule(hour = "*", minute = "*/5", persistent = false) public void scheduledTask() { System.out.println("Running scheduled task"); } } ``` ### Step 3: Create resources.xml for Data Sources For TomEE, use `resources.xml` instead of Tomcat's `context.xml`. Create `src/main/webapp/WEB-INF/resources.xml`: ```xml <?xml version='1.0' encoding='utf-8'?> <resources> <Resource id="jdbc/DefaultDB" provider="xs.openejb:XS Default JDBC Database" type="javax.sql.DataSource"> service=${service_name_for_DefaultDB} </Resource> </resources> ``` > **Note:** TomEE uses `xs.openejb:XS Default JDBC Database` provider instead of Tomcat's `TomcatDataSourceFactory`. The `service` placeholder is specified as element content, not as an XML attribute. ### Step 4: Configure persistence.xml for TomEE JTA If the application uses JPA, the `persistence.xml` must be updated for TomEE's JTA environment. There are four critical changes: 1. **File location** — Move `persistence.xml` from `src/main/resources/META-INF/` to `src/main/webapp/META-INF/`. TomEE processes DDL generation correctly only when the persistence.xml is at the WAR root `META-INF/` location, not at `WEB-INF/classes/META-INF/`. 2. **Explicit EclipseLink provider** — TomEE defaults to OpenJPA. Without an explicit `<provider>`, EclipseLink may not be properly initialized as the JPA provider. 3. **Short JNDI datasource name** — TomEE resolves datasources differently than Neo. Use `jdbc/DefaultDB` without the `java:comp/env/` prefix. 4. **HANA Cloud NCLOB for large text columns** — HANA Cloud limits `NVARCHAR` to 5000 characters. Any `@Lob` field with `length > 5000` must use `columnDefinition = "NCLOB"` instead of `length`, otherwise DDL generation silently fails for those tables. **Before (Neo):** ```xml <!-- Location: src/main/resources/META-INF/persistence.xml --> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="MyApp" transaction-type="JTA"> <jta-data-source>java:comp/env/jdbc/DefaultDB</jta-data-source> <class>com.example.MyEntity</class> <properties> <property name="eclipselink.ddl-generation" value="create-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> </properties> </persistence-unit> </persistence> ``` **After (Cloud Foundry TomEE):** ```xml <!-- Location: src/main/webapp/META-INF/persistence.xml (MUST be under webapp, not resources) --> <persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" version="3.0"> <persistence-unit name="MyApp" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/DefaultDB</jta-data-source> <class>com.example.MyEntity</class> <properties> <property name="eclipselink.ddl-generation" value="create-or-extend-tables" /> <property name="eclipselink.target-database" value="HANA"/> </properties> </persistence-unit> </persistence> ``` **Key changes:** - **File moved** from `src/main/resources/META-INF/` to `src/main/webapp/META-INF/` — TomEE's DDL generation only runs correctly when persistence.xml is at the WAR root `META-INF/` location. Placing it under `resources/META-INF/` (which maps to `WEB-INF/classes/META-INF/` in the WAR) causes DDL generation to silently fail. - `<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>` — explicit EclipseLink provider (TomEE defaults to OpenJPA) - `<jta-data-source>jdbc/DefaultDB</jta-data-source>` — short JNDI name without `java:comp/env/` prefix - `eclipselink.ddl-generation=create-or-extend-tables` — use this value instead of `create-tables` for robustness during schema evolution > **Warning:** If `persistence.xml` is placed under `src/main/resources/META-INF/` instead of `src/main/webapp/META-INF/`, EclipseLink's DDL generation will **silently fail** in TomEE — no tables will be created and no error will be logged at startup. The failure only becomes visible at runtime when queries hit missing tables. Always verify by adding `<property name="eclipselink.logging.level" value="FINE"/>` temporarily and checking for `CREATE TABLE` statements in the logs. #### HANA Cloud @Lob Column Migration HANA Cloud enforces a maximum of **5000 characters** for `NVARCHAR` columns. EclipseLink maps `@Lob @Column(length = N)` to `NVARCHAR(N)` — if `N > 5000`, the `CREATE TABLE` statement fails silently. **Before (works on Neo HANA on-premise, fails on HANA Cloud):** ```java @Lob @Column(nullable = false, length = 16 * 1024) // 16384 > 5000 limit private String longText = ""; @Lob @Column(length = 512 * 1024) // 524288 > 5000 limit private String introduction = ""; ``` **After (works on HANA Cloud):** ```java @Lob @Column(nullable = false, columnDefinition = "NCLOB") private String longText = ""; @Lob @Column(columnDefinition = "NCLOB") private String introduction = ""; ``` Replace `length = N` with `columnDefinition = "NCLOB"` on every `@Lob` field where the original length exceeds 5000. Keep other `@Column` attributes (`nullable`, `updatable`) as-is. > **Note:** `NCLOB` has no practical size limit on HANA Cloud and is the correct type for large text fields. Fields with `length <= 5000` (e.g., `@Column(length = 1024)`) can remain as `NVARCHAR` and do not need this change. > 🛑 **HARD RULE — a JPA/EJB app REQUIRES a HANA schema service. "No services > required" is wrong for any app with a `persistence.xml` or a JPA datasource.** > The `resources.xml` from Step 3 binds `jdbc/DefaultDB` to > `service=${service_name_for_DefaultDB}`. If the mtad does not bind a > `com.sap.xs.hana-schema` service (Steps 5–6), TomEE cannot initialise the > datasource / persistence unit at startup, and the app **stages successfully > but crashes on boot** (`cf deploy` → "Some instances have crashed", no useful > HTTP response). Steps 5 and 6 are **mandatory** whenever the app uses JPA — > do not skip them and do not declare "no services required". > > ✅ **Verify before deploy:** the mtad must contain a > `type: com.sap.xs.hana-schema` resource AND the module must `requires:` it. > `grep -q 'com.sap.xs.hana-schema' <mtad>` must succeed for a persistence app. ### Step 5: Create resource_configuration.yml Create `src/main/webapp/META-INF/sap_java_buildpack/config/resource_configuration.yml`: ```yaml --- tomee/webapps/ROOT/WEB-INF/resources.xml: service_name_for_DefaultDB: ${app-name}-hana ``` > **Note:** The path is `tomee/webapps/ROOT/WEB-INF` instead of `tomcat/webapps/ROOT`. > > 🛑 **SUBSTITUTE `${app-name}` with the REAL app name — it is a placeholder, not > a literal.** This value MUST exactly equal the `hana-schema` resource name you > bind in the mtad (Step 6). If you leave it literal, the buildpack looks up a > service called `app-name-hana` that does not exist, logs > `Could not find service with name 'app-name-hana', known services > '[<real>-hana]'`, the JDBC pool fails to initialise, and the app **crashes on > startup**. Example for an app named `persistence-with-ejb`: > > ```yaml > --- > tomee/webapps/ROOT/WEB-INF/resources.xml: > service_name_for_DefaultDB: persistence-with-ejb-hana > ``` > > ✅ **Cross-check:** the value here must be identical to the `resources:` entry
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub