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.

معلومات المصدر

المستودع
SAP-samples/btp-neo-java-app-migration
آخر نشاط في المصدر
٢٩ يوليو ٢٠٢٦ في ١٣:٢٦
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٦
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
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
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub