İçeriğe geç

WAR ve Uygulama Sunucusu — Tomcat'te Çalışan, WildFly'da Neden Açılmadı?

Orta 9 dk Sık karşılaşılır

Önce şunu oku: Auto-configuration — Bu Bean Nereden Geldi?

30 saniyede özet

Bir WAR, kendi başına değil bir sunucunun içinde çalışır. Sunucunun konuştuğu paket adları (javax ya da jakarta) uymalı ve her kütüphanenin tek bir sahibi olmalı: Tomcat JPA getirmez, WildFly getirir.

Yeni bir eve taşınıyorsun. Eşyalı dairede buzdolabı zaten vardır; kendi buzdolabını da getirirsen mutfağa sığmaz. Eşyasız dairede ise buzdolabını sen getirmezsen hiç olmaz.

  1. Bayt: Rapor uygulaması Tomcat'te sorunsuz çalışıyor. Şirket WildFly'a geçiyor; WAR'ı oraya kopyalayalım!

  2. Sen: WildFly açılışta hata verdi. Hibernate sınıflarıyla ilgili bir şey diyor.

  3. Bayt: Ama aynı WAR! Tomcat'te hiç şikâyet etmemişti.

  4. Bayt: Aynı WAR, ama ev farklı. Bu ev neyi kendisi getiriyor?

WAR bir misafirdir

Spring Boot uygulaması çoğu zaman kendi Tomcat’ini içinde taşıyan çalıştırılabilir bir JAR’dır. Bir WAR ise bir sunucuya yüklenir ve o sunucunun içinde çalışır.

Bu yüzden WAR iki soruya cevap vermelidir: sunucuyla aynı paket adlarını mı konuşuyor, ve hangi kütüphaneleri sunucu, hangilerini WAR getiriyor?

Kafam karıştı, daha basit anlat

WAR bir sunucunun içinde çalışır. Sunucunun dilini konuşmalı ve neyi kimin getirdiğini bilmeli.

Hızlı kontrolBaşlangıç

Bir WAR ile çalıştırılabilir (fat) JAR arasındaki temel fark nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

WAR bir sunucuya konmadan önce hangi iki soru cevaplanmalı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

javax mı, jakarta mı?

Java EE, Jakarta EEJava EE'nin yeni adı. Paket adları javax.* yerine jakarta.* oldu; Tomcat 10, güncel WildFly ve Spring Boot 3 jakarta kullanır.Sözlükte gör → adını aldığında paket adları da javax.* yerine jakarta.* oldu. Tomcat 9 javax.servlet konuşur; Tomcat 10 ve güncel WildFly jakarta.servlet konuşur.

javax.servlet ile derlenmiş bir WAR, Tomcat 10’a konulduğunda sunucu onun servlet’lerini tanımaz. Spring Boot 3 de jakarta.* kullandığı için, bu geçiş çoğu zaman sürüm yükseltmesiyle birlikte gelir.

Kafam karıştı, daha basit anlat

Tomcat 9 javax, Tomcat 10 ve güncel WildFly jakarta konuşur.

Hızlı kontrolOrta

Tomcat 10 hangi servlet paketlerini kullanır?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

javax.servlet ile derlenmiş WAR Tomcat 10'a konuldu. Ne olur?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kim neyi getirir?

WAR, jakarta ile derlenmiş ve içinde kendi Hibernate'ini taşıyor. Tomcat 10'da sorunsuz açılıyor. Aynı WAR'ı güncel WildFly'a koyarsan ne olur? Cevabı göster

Açılmayabilir. WildFly kendi Hibernate’ini getirir. WAR’ın içindeki ikinci kopya, sunucununkiyle çakışır ve aynı ada sahip iki sınıf birbirinin yerine geçmeye çalışır.

Ev ne veriyorsa getirme, vermiyorsa getir.
Adım adım oku
  1. Eşyalı daire: buzdolabı var.
  2. Kendi buzdolabını da getirdin.
  3. Eşyasız daire: buzdolabı yok.
  4. Ev ne veriyorsa getirme, vermiyorsa getir.

Tomcat bir servlet kapsayıcısıYalnızca web katmanını (servlet) çalıştıran sunucu, örneğin Tomcat. JPA gibi kurumsal kütüphaneleri getirmez; tam uygulama sunucusu (WildFly) getirir.Sözlükte gör →: yalnızca web katmanını verir, JPA vermez. WildFly tam bir uygulama sunucusudur ve JPA’yı kendi Hibernate’iyle getirir. Sunucunun getirdiği kütüphane Maven’da provided olarak işaretlenir ve WAR’a girmez.

Kafam karıştı, daha basit anlat

Tomcat’e Hibernate’i sen getirirsin. WildFly’a getirmezsin; provided yazarsın.

Hızlı kontrolOrta

WAR'ın içinde Hibernate var ve WildFly'a konuldu. Sorun ne olabilir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kendin gör

Rapor uygulaması uygulama sunucusuna gidiyor

Tohum 798859

Sunucu getirir

jakarta.servlet

— JPA yok

WAR getirir

javax.servlet ile derlenmiş

— Hibernate yok

  1. · servlet paketleri
  2. · JPA / Hibernate
  3. · açılış

· yükleniyor…

Hız
Adım 0

Şu an ne oldu?

Kontrol: servlet

WAR ile sunucu aynı dili konuşuyor mu, kim neyi getiriyor?

Görevler0/3

  • WAR, paket adları yüzünden yüklenmesinaçık

    İpucu

    javax ile derlenmiş WAR'ı Tomcat 10'a koy.

  • İki Hibernate kopyası çakışsınaçık

    İpucu

    WildFly ve WAR içinde Hibernate.

  • Uygulama WildFly'da açılsınaçık

    İpucu

    jakarta, Hibernate sunucudan.

Olay günlüğü (0)

Henüz olay yok. Oynat veya adımla.

  1. Varsayılanla oynat. javax ile derlenmiş WAR Tomcat 10’a yüklenmedi.
  2. Paketleri jakarta, Hibernate’i WAR içinde yap. Tomcat 10’da açıldı.
  3. Sunucuyu WildFly yap. İki Hibernate kopyası çakıştı. Sonra “Hibernate WAR içinde”yi kapat: açıldı.
Hızlı kontrolOrta

Simülatörde Tomcat 10, jakarta ve Hibernate WAR içinde: neden açıldı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Tuzaklar

Gizli gelen kopya. Hibernate’i sen eklemesen de başka bir kütüphane onu geçişli olarak getirebilir. mvn dependency:tree ile WAR’a neyin girdiğine bak.

Gömülü Tomcat’i unutmak. Spring Boot uygulamasını WAR olarak bir sunucuya koyarken gömülü Tomcat’i provided yap. Yoksa WAR’ın içinde ikinci bir sunucu taşırsın.

Sunucunun kütüphanesini istemeden ezmek. Kendi sürümünü kullanmak zorundaysan, WildFly’da bunu jboss-deployment-structure.xml ile açıkça söyle. Kazara olan bir çakışma, açılışta değil gece yarısı patlayabilir.

Kafam karıştı, daha basit anlat

WAR’ın içine bak, gömülü Tomcat’i provided yap, sunucunun kütüphanesini açıkça dışarıda bırak.

Hızlı kontrolOrta

Hibernate'i pom.xml'e hiç eklemedin ama WAR'ın içinde çıktı. Neden?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aşağıda WildFly’a giden bir Spring Boot rapor uygulamasının WAR ayarı var: servlet katmanı ve JPA sunucudan gelir.

Derinleş · Rapor uygulaması: WildFly için WAR 3 dosya · ~67 satır · ilk okumada atlayabilirsin
Proje dosyaları

report/ pom.xml pom.xml: packaging war; gömülü Tomcat ve Hibernate provided, çünkü ikisini de sunucu getirir.

report/pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
</parent>
<groupId>com.bank.custody</groupId>
<artifactId>report</artifactId>
<version>2.0.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- The server is the servlet container: no embedded Tomcat inside the WAR. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<!-- WildFly brings its own Hibernate. -->
<exclusion>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

report/src/main/java/com/bank/custody/report/ ReportApplication.java ReportApplication: SpringBootServletInitializer, sunucunun uygulamayı başlatmasını sağlar.

report/src/main/java/com/bank/custody/report/ReportApplication.java
package com.bank.custody.report;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class ReportApplication extends SpringBootServletInitializer {
/** Called by the application server when it deploys the WAR. */
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(ReportApplication.class);
}
/** Still runnable on its own for local development. */
public static void main(String[] args) {
SpringApplication.run(ReportApplication.class, args);
}
}

report/src/main/resources/ application.yml persistence ayarı: veri kaynağı sunucuda tanımlı; uygulama onu JNDI adıyla bulur.

report/src/main/resources/application.yml
spring:
datasource:
jndi-name: java:jboss/datasources/CustodyDS # defined on the server, not in the WAR
jpa:
open-in-view: false

Kendini sına

Şimşek turu1/4

Tomcat 10, javax.servlet ile derlenmiş bir WAR'ı çalıştırır.

Soru 1/3İleri

Spring Boot uygulamasını WAR olarak WildFly'a koyarken gömülü Tomcat ne yapılmalı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aklında kalacak üç şey

  1. 1 Tomcat 10 ve güncel WildFly jakarta.* paketlerini konuşur; javax.* ile derlenmiş bir WAR orada yüklenmez.
  2. 2 Tomcat bir servlet kapsayıcısıdır ve JPA getirmez; WildFly tam bir uygulama sunucusudur ve kendi Hibernate'ini getirir.
  3. 3 Sunucunun getirdiği kütüphane WAR'a provided olarak girer; getirmediği WAR'ın içinde gelir. Her kütüphanenin tek bir sahibi olur.
0/4 kart bu dersten toplandı