6 Mayıs 2022 Cuma

Wildfly JNDI DataSource Ekleme

Giriş
Uygulamadan bir DataSource'a erişmek için 3 tane yöntem var.
1. Uygulama içinde tanımlanır
2. Wildfly Üzerinde Modul Olarak Tanımlanır Ancak Wildfly Ayarlarına Driver Eklenmez
3. Wildfly Üzerinde Modul Olarak Tanımlanır ve Wildfly Ayarlarına Driver + DataSource eklenir. Uygulama JNDI üzerinden erişir. Bir örnek burada.

Örnek - MySQL
WILDFLY_HOME/modules/system/layers/base/com/mysql/main/module.xml dosyasında şöyle yaparız
<module xmlns="urn:jboss:module:1.5" name="com.mysql">
  <resources>
    <resource-root path="mysql-connector-java-8.0.17.jar" />
  </resources>
  <dependencies>
    <module name="javax.api"/>
    <module name="javax.transaction.api"/>
  </dependencies>
</module>
Daha sonra
1. Configuration -> Subsystems -> Datasources & Drivers -> JDBC Drivers menüsü ile bir driver eklenir. Ekrandaki bilgiler şöyle
Driver Name : mysql
Driver Module Name : com.mysql
Driver Class Name : com.mysql.cj.jdbc.Driver
Driver XA Datasourc Class Nam : com.mysql.cj.jdbc.MysqlXADataSource
2. Configuration -> Subsystems -> Datasources & Drivers -> Datasources menüsü ile bir XA olmayan datasource eklenir. Buradaki parametreleri veremiyorum. Kendi veri tabanınıza göre ayarlamanız gerekiyor.

Örnek - postgre
$WILDFLY_HOME\modules\org\postgres\main\module.xml dosyasında şöyle yaparız
<?xml version='1.0' encoding='UTF-8'?>
<module xmlns="urn:jboss:module:1.1" name="org.postgres">

    <resources>
        <resource-root path="postgresql-9.4-1204-jdbc4.jar"/>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
        <module name="javax.servlet.api" optional="true"/>
    </dependencies>
</module>
DataSource olarak şöyle yaparız
<datasource jta="false" jndi-name="java:jboss/datasources/YourDS" pool-name="YourDS"
  enabled="true" use-ccm="false">
    <connection-url>jdbc:postgresql://localhost:5432/yourDB</connection-url>
    <driver>postgres</driver>
    <security>
        <user-name>user</user-name>
        <password>pass/password>
    </security>
    <validation>
        <validate-on-match>false</validate-on-match>
        <background-validation>false</background-validation>
    </validation>
    <statement>
        <share-prepared-statements>false</share-prepared-statements>
    </statement>
</datasource>

<drivers>
    <driver name="postgres" module="org.postgres">
        <driver-class>org.postgresql.Driver</driver-class>
    </driver>
</drivers>
Örnek - gridgain-community-8.8.9
Bunu 
JDK 8, Wildfly 25 ve standalone.xml ve ignite-core-8.8.9.jar ile denedim ve çalıştı
JDK 11, Wildfly 25 ve standalone.xml ve ignite-core-8.8.9.jar ile denedim ve çalıştı
JDK 16, Wildfly 25 ve standalone.xml ve ignite-core-8.8.9.jar ile denedim ve çalıştı.

jar dosyasına bakınca MANIFEST.MF dosyasında şunu görüyorum. Yani gridgain-community-8.8.9.jar JDK 8 ile derlenmiş.
Created-By: Apache Maven Bundle Plugin
Build-Jdk: 1.8.0_291
JDK 16 ile çalışması için bazı ayarlar yapmak gerekiyor. Şöyle yaparız
set JAVA_OPTS=--add-modules jdk.unsupported --add-opens=java.base/java.nio=ALL-UNNAMED
Eğer bunu yapmazsak hata olarak şunu veriyor.
 Operation ("add") failed - address: ([
    ("subsystem" => "datasources"),
    ("jdbc-driver" => "ignite")
]): java.lang.ExceptionInInitializerError
at org.apache.ignite@8.8.9//org.apache.ignite.internal.util.IgniteUtils.<clinit>(IgniteUtils.java:865)
at org.apache.ignite@8.8.9//org.apache.ignite.lang.IgniteProductVersion.fromString(IgniteProductVersion.java:311)
at org.apache.ignite@8.8.9//org.apache.ignite.internal.IgniteVersionUtils.<clinit>(IgniteVersionUtils.java:99)
at org.apache.ignite@8.8.9//org.apache.ignite.IgniteJdbcThinDriver.<clinit>(IgniteJdbcThinDriver.java:139)
 sebebi de sun.misc.Unsafe sınıfının artık jdk.unsupported içinde olması. Yani artık JDK 8'den sonra direkt kullanılamıyor.

sun.misc.unsafe JDK 11 src.zip dosyasının içinde "jdk.unsupported" dizininde halen bu sınıflar görülebilir. Ancak JDK 11 module' e bir şekilde erişim izni verirken, JDK 16 vermiyor.

JDK 8, Wildfly 12 ve standalone.xml ile denedim ve çalışmadı. Hata olarak şunu veriyor sebebini de bilmiyorum. Her şeyi aynı tutarak ignite-core-2.11.0.jar ile de denedim. Yine aynı hatayı aldım. Aslında Wildfly 12 eski olduğu için de daha fazla uğraşmadım.
Operation ("add") failed - address: ([
    ("subsystem" => "datasources"),
    ("jdbc-driver" => "ignite")
]): java.lang.NoClassDefFoundError: sun/misc/Unsafe
at org.apache.ignite.internal.util.IgniteUtils.unsafeByteArrayCopyAvailable(IgniteUtils.java:9413)
at org.apache.ignite.internal.util.IgniteUtils.<clinit>(IgniteUtils.java:344)
at org.apache.ignite.lang.IgniteProductVersion.fromString(IgniteProductVersion.java:311)
at org.apache.ignite.internal.IgniteVersionUtils.<clinit>(IgniteVersionUtils.java:99)
at org.apache.ignite.IgniteJdbcThinDriver.<clinit>(IgniteJdbcThinDriver.java:139)
$WILDFLY_HOME\modules\org\apache\ignite\main\module.xml dosyasında şöyle yaparız
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.1" name="org.ignite.jdbc">
    <resources>
        <resource-root path="ignite-core-8.8.9.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>
</module>
Şöyle yaparız. Kendi tanımımda use-java-context ve statistics-enabled yok ancak ekleyince de sorun çıkmıyor
<datasources>
  <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" 
    use-java-context="true" 
statistics-enabled="${wildfly.datasources.statistics-enabled: ${wildfly.statistics-enabled:false}}">
    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1; DB_CLOSE_ON_EXIT=FALSE</connection-url>
    <driver>h2</driver>
    <security>
      <user-name>sa</user-name>
      <password>sa</password>
    </security>
  </datasource>
  
  <datasource jndi-name="java:jboss/datasources/IgniteDS" pool-name="ignitedatasource">
    <connection-url>jdbc:ignite:thin://localhost:10800/</connection-url>
    <driver>ignite</driver>
      <pool>
        <min-pool-size>1</min-pool-size>
      </pool>
  </datasource>
  
  <drivers>
    <driver name="h2" module="com.h2database.h2">
      <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
    </driver>
    <driver name="ignite" module="org.apache.ignite">
      <driver-class>org.apache.ignite.IgniteJdbcThinDriver</driver-class>
    </driver>
  </drivers>
</datasources>
Bunu test etmek için şöyle yaparız
>jboss-cli.bat --connect
[standalone@localhost:9990 /]/subsystem=datasources/data-source=ignitedatasource:
test-connection-in-pool
{
    "outcome" => "success",
    "result" => [true]
}
Data Source ve JTA
JTA transaction istiyorsak jta=true yapılmalı
Örnek
Şöyle yaparız
<datasource jta="false" jndi-name="java:/wt/testds" pool-name="testds" enabled="true"
  use-ccm="false">  
...  
</datasource> 
Data Source ve statistics-enabled
statistics-enabled true ise Runtime/Datasources altında connection pool için istatistiki bilgiler görülebilir
Örnek
Şöyle yaparız
datasource jndi-name="java:/fooDS" 
  pool-name="fooDS" 
  statistics-enabled="true">
  ..
</datasource>

25 Nisan 2022 Pazartesi

Jakarta EE @ConfigProperty Anotasyonu

Giriş
Şu satırı dahil ederiz
import javax.resource.spi.ConfigProperty;
Jakarta EE ResourceAdapter Arayüzünü tanımlarken pek çok bilgi XML içindedir. XML içindeki tag'lerden bazılarını @Connector Anotasyonu ile koda almak mümkün. 

Örnek
Şöyle yaparız
@ConfigProperty
private String token;

Jakarta EE @Connector Anotasyonu

Giriş
Şu satırı dahil ederiz
import javax.resource.spi.Connector;
Jakarta EE ResourceAdapter Arayüzünü tanımlarken pek çok bilgi XML içindedir. XML içindeki tag'lerden bazılarını @Connector Anotasyonu ile koda almak mümkün. 

displayName Alanı
Örnek
src/main/resources/META-INF/ra.xml dosyasında şöyle olsun
<connector ...> 
  <description></description>
  <display-name>MyResourceAdapter</display-name>
  <vendor-name>Java EE Tutorial</vendor-name>
  <eis-type></eis-type>
  <resourceadapter-version></resourceadapter-version>                                  
  <resourceadapter>
  
    <resourceadapter-class>
      com.foo.MyResourceAdapter
     </resourceadapter-class>
	  
      <config-property>
        <config-property-name>input</config-property-name>
	  <config-property-type>java.lang.String</config-property-type>
	  <config-property-value>mystring value</config-property-value>
      </config-property>
		
		
      <inbound-resourceadapter>
        <messageadapter>
          <messagelistener>
	    <messagelistener-type>com.InboundMessageEndpoint</messagelistener-type>
	      <activationspec>
	        <activationspec-class>com.EndpointActivationSpec</activationspec-class>
              </activationspec>
	  </messagelistener>
	</messageadapter>
      </inbound-resourceadapter>
	
  </resourceadapter>
</connector>
connector tag'indeki bazı bilgileri koda almak için şöyle yaparız
@Connector(
  displayName = "MyResourceAdapter",
  vendorName = "Java EE Tutorial",
  version = "7.0"
)
public class TrafficResourceAdapter implements ResourceAdapter, Serializable {
  ...
}
description Alanı
Örnek
Şöyle yaparız
@Connector(description = "Sample Resource Adapter", 
  displayName = "Sample Resource Adapter", 
  eisType = "Sample Resource Adapter", 
  version = "1.0")
public class SlackResourceAdapter implements ResourceAdapter {

  public void start(final BootstrapContext bootstrapContext) 
    throws ResourceAdapterInternalException {
  }

  public void stop() {
  }

  public void endpointActivation(MessageEndpointFactory messageEndpointFactory,
    ActivationSpec activationSpec)
    throws ResourceException {
  }

  public void endpointDeactivation(MessageEndpointFactory messageEndpointFactory,
    ActivationSpec activationSpec) {
  }

  public XAResource[] getXAResources(final ActivationSpec[] activationSpecs)
    throws ResourceException {
      return new XAResource[0];
  }
}

22 Nisan 2022 Cuma

Wildfly standalone.sh

-c seçeneği
Örnek
Şöyle yaparız
# This will boot WildFly in standalone mode and bind to all interfaces
/opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0 -c standalone-full.xml

19 Nisan 2022 Salı

EJB @MessageDriven Anotasyonu

Örnek
Şöyle yaparız. destination kuyruk ismini belirtir. destinationType Queue veya Topic olduğunu belirtir, maxSession ise kaç tane eş zamanlı mesaj işleneceğini belirtir.
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName="destination", propertyValue="SendingSMSQueue"),
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="maxSession", propertyValue = "1")
})
public class SendgridEmail2SmsMessageListener implements MessageListener {...}


Wildfly Logging

Giriş
Loglama ayarları 
1. yönetim ekranından 
2. jboss-cli komutuyla 

değiştirilebiliyor. 

Ancak hangisi kullanılırsa kullanılsın, çalışma zamanında (run-time) loglama seviyesini dinamik olarak değiştirebilmenin bir yolunu bulamadım. Her iki komutta sadece standalone.xml'i değiştiriyor. Ya da hangi xml'i kullanıyorsak

Değişiklikleri Wildfly'ın tekrar okuması için Cli satırından "reload" yapmak gerekiyor.

Örnek - Custom Logger
Şöyle yaparız
<subsystem xmlns="urn:jboss:domain:logging:8.0">
<console-handler name="CONSOLE">
<level name="INFO"/>
<formatter>
<named-formatter name="COLOR-PATTERN"/>
</formatter>
</console-handler>
<periodic-rotating-file-handler name="FILE" autoflush="true">
<formatter>
<named-formatter name="PATTERN"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<logger category="com.foo">
<level name="DEBUG"/>
</logger>

<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>
<formatter name="PATTERN">
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
</formatter>
<formatter name="COLOR-PATTERN">
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
</formatter>
</subsystem>
Örnek - Root Logger
Şöyle yaparız
$JBOSS_HOME/bin/jboss-cli.sh -c

[standalone@localhost:9990 /] /subsystem=logging/console-handler=CONSOLE:write-attribute(name=level,value=DEBUG)
{"outcome" => "success"}

[standalone@localhost:9990 /] /subsystem=logging/root-logger=ROOT:write-attribute(name=level,value=DEBUG)
{"outcome" => "success"}
xml şöyle olur
<root-logger>
  <level name="DEBUG"/>
       <handlers>
          <handler name="CONSOLE"/>
          <handler name="FILE"/>
       </handlers>
</root-logger>



18 Nisan 2022 Pazartesi

Docker ve Wildfly

Örnek - Kullanmayın
Kullanmayın çünkü "jboss/wildfly" artık "quay.io" olarak değişti. Şöyle yaparız
FROM jboss/wildfly
ADD my-app.war /opt/jboss/wildfly/standalone/deployments/
ve şöyle yaparız
docker build --tag=my-app . && docker run -it my-app
Örnek - quay.io 
Şöyle yaparız. -b ile bind seçenekleri belirtiliyor.
FROM quay.io/wildfly/wildfly:26.0.0.Final
COPY my-standalone.xml /opt/jboss/wildfly/standalone/configuration/
#Deploy
COPY ./target/*.war /opt/jboss/wildfly/standalone/deployments/

# Run with custom configuration
CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0",
  "-c","my-standalone.xml"]
Bu image için kullanılan DockerFile GitHub'da burada. Burada FROM jboss/base-jdk:11 görülebilir.
jboss/base-jdk:11 için kullanılan DockerFile GitHub'da burada. FROM jboss/base:latest görülebilir
jboss/base için kullanılan DockerFile GitHub'da burada. FROM centos:7 görülebilir

Örnek -  quay.io  + runtime
Şöyle yaparız
FROM quay.io/wildfly/wildfly-runtime-jdk11
COPY --chown=jboss:root target/server $JBOSS_HOME
RUN chmod -R ug+rwX $JBOSS_HOME
Örnek - Admin Kullanıcısı
Şöyle yaparız
FROM quay.io/wildfly/wildfly
#Create user
RUN /opt/jboss/wildfly/bin/add-user.sh admin Admin#70365 --silent

CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0"]
Örnek - Olmayan bir Wildfly Sürümünü İndir ve JDK Kur
Şöyle yaparız. Burada JDK 17 de kuruluyor
#Bring centos
FROM redhat/ubi8

# Create a user and group used to launch processes
# The user ID 1000 is the default for the first "regular" user on Fedora/RHEL,
# so there is a high chance that this ID will be equal to the current user
# making it easier to use volumes (no permission issues)
RUN groupadd -r jboss -g 1000 && useradd -u 1000 -r -g jboss -m -d /opt/jboss -s /sbin/nologin -c "JBoss user" jboss && \
    chmod 755 /opt/jboss

# Set the working directory to jboss' user home directory
WORKDIR /opt/jboss

# Install JDK 17
RUN yum -y install java-17-openjdk-devel && yum clean all

# Switch back to jboss user
USER jboss

# Set the JAVA_HOME variable to make it clear where Java is located
ENV JAVA_HOME /usr/lib/jvm/java

##Install Wildfly
# Set the WILDFLY_VERSION env variable
ENV WILDFLY_VERSION 25.0.0.Final
ENV WILDFLY_SHA1 238e67f48f1bd1e79f2d845cba9194dcd54b4d89
ENV JBOSS_HOME /opt/jboss/wildfly

USER root

# Add the WildFly distribution to /opt, and make wildfly the owner of the extracted tar content
# Make sure the distribution is available from a well-known place
RUN cd $HOME \
    && curl -L -O https://github.com/wildfly/wildfly/releases/download/$WILDFLY_VERSION/wildfly-$WILDFLY_VERSION.tar.gz \
    && sha1sum wildfly-$WILDFLY_VERSION.tar.gz | grep $WILDFLY_SHA1 \
    && tar xf wildfly-$WILDFLY_VERSION.tar.gz \
    && mv $HOME/wildfly-$WILDFLY_VERSION $JBOSS_HOME \
    && rm wildfly-$WILDFLY_VERSION.tar.gz \
    && chown -R jboss:0 ${JBOSS_HOME} \
    && chmod -R g+rw ${JBOSS_HOME}

# Create folders for batch processing
RUN bash -c 'mkdir -p /advdata/TspFt/BatchProcessingRoot/rwbat/{input,tmp,output,classicInput,classicTmp,classicOutput}'
RUN chown -R jboss /advdata/TspFt/BatchProcessingRoot/rwbat/

# Ensure signals are forwarded to the JVM process correctly for graceful shutdown
ENV LAUNCH_JBOSS_IN_BACKGROUND true

USER jboss

# Expose the ports in which we're interested
EXPOSE 8080
EXPOSE 9990


#Deploy
ADD  modules/system/layers/base/com /opt/jboss/wildfly/modules/system/layers/base/com/
COPY standalone-full.xml /opt/jboss/wildfly/standalone/configuration
COPY ./build/libs/rwGuiEar.ear /opt/jboss/wildfly/standalone/deployments/

#Create user
RUN /opt/jboss/wildfly/bin/add-user.sh admin Admin#70365 --silent

# Set the default command to run on boot
# This will boot WildFly in standalone mode and bind to all interfaces
CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0", "-c","standalone-full.xml"]
Eğer deploy işlemini bir artifactory sunucusundan yapıyorsak şöyle yaparız
...

USER root
RUN curl http://artifactory.foo.com/artifactory/release-local/mysql-connector-java-8.0.17.jar > /opt/jboss/wildfly/modules/system/layers/base/com/mysql/main/mysql-connector-java-8.0.17.jar

USER jboss
COPY files/standalone-full.xml /opt/jboss/wildfly/standalone/configuration
RUN curl http://artifactory.foo.com/release/rwGuiEar.ear > /opt/jboss/wildfly/standalone/deployments/rwGuiEar.ear

...
Çalıştırmak için şöyle yaparız. Burada yerelde çalışan vitesstestserver isimli container, wildfly25 ile aynı ağa alınıyor
# Create a network
docker network create myNetwork

# build image
docker build -t wildfly25 .
docker run -d --rm --network myNetwork --name wildfly25
  -p 8080:8080 -p 9990:9990 wildfly25

# Connect a running container to a network
docker network connect myNetwork vitesstestserver
veya vitesstestserver'ı başlatırken ağa almak için şöyle yaparız
docker build -t vitesstestserver .
docker run --rm --name vitesstestserver --network myNetwork
  -p 33577:33577 vitesstestserver
Bağlanmak için şöyle yaparız
http://localhost:8080/rwgui/
Örnek - /usr/sbin/sshd kullanan Redhat/ubi8
Burada wildfly + ssh kuruluyor. Şöyle yaparız
#Bring OS
FROM redhat/ubi8

# Create a user and group that is used to launch processes
# The user ID 1000 is the default for the first "regular" user on Fedora/RHEL,
# so there is a high chance that this ID will be equal to the current user
# making it easier to use volumes (no permission issues)
RUN groupadd -r jboss -g 1000 && useradd -u 1000 -r -g jboss -m -d /opt/jboss -c "JBoss user" jboss && \
    chmod 755 /opt/jboss


# Set the working directory to jboss user's home directory
WORKDIR /opt/jboss

# Install SSH Server, JDK 17
RUN yum -y install \
    sudo \
    openssh-server \
    openssh-clients \
    java-17-openjdk-devel && yum clean all

USER jboss
RUN ssh-keygen -A

USER root
RUN ssh-keygen -A

# Set passwords
RUN echo root:login-1 | chpasswd
RUN echo jboss:login-1 | chpasswd

# Set the JAVA_HOME variable to make it clear where Java is located
ENV JAVA_HOME /usr/lib/jvm/java

##Install Wildfly
# Set the WILDFLY_VERSION env variable
ENV WILDFLY_VERSION 25.0.0.Final
ENV WILDFLY_SHA1 238e67f48f1bd1e79f2d845cba9194dcd54b4d89
ENV JBOSS_HOME /opt/jboss/wildfly

ADD start.sh /
RUN chmod +x /start.sh

# Add the WildFly distribution to /opt/jboss, and make jboss user the owner of the extracted tar content
# Make sure the distribution is available from a well-known place
RUN cd $HOME \
    && curl -L -O https://github.com/wildfly/wildfly/releases/download/$WILDFLY_VERSION/wildfly-$WILDFLY_VERSION.tar.gz \
    && sha1sum wildfly-$WILDFLY_VERSION.tar.gz | grep $WILDFLY_SHA1 \
    && tar xf wildfly-$WILDFLY_VERSION.tar.gz \
    && mv $HOME/wildfly-$WILDFLY_VERSION $JBOSS_HOME \
    && rm wildfly-$WILDFLY_VERSION.tar.gz \
    && chown -R jboss:0 ${JBOSS_HOME} \
    && chmod -R g+rw ${JBOSS_HOME}

# Create folders for batch processing
RUN bash -c 'mkdir -p /advdata/TspFt/BatchProcessingRoot/rwbat/{input,tmp,output,classicInput,classicTmp,classicOutput}'
RUN chown -R jboss /advdata/TspFt/BatchProcessingRoot/rwbat/

# Ensure signals are forwarded to the JVM process correctly for graceful shutdown
ENV LAUNCH_JBOSS_IN_BACKGROUND true

USER jboss

# Expose the ports in which we're interested
EXPOSE 22
EXPOSE 8080
EXPOSE 9990


#Deploy local files
ADD  modules/system/layers/base/com /opt/jboss/wildfly/modules/system/layers/base/com/
COPY standalone-full.xml /opt/jboss/wildfly/standalone/configuration
COPY ./build/libs/rwGuiEar.ear /opt/jboss/wildfly/standalone/deployments/

#Create user on wildfly for management
RUN /opt/jboss/wildfly/bin/add-user.sh admin login-1 --silent

# Run as root
USER root

# Set the default command to run on boot
CMD ["/start.sh"]
start.sh şöyle
#!/bin/bash
/usr/sbin/sshd -D &

# This will boot WildFly in standalone mode and bind to all interfaces
sudo -u jboss /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0 -c standalone-full.xml
Örnek 
4 tane ubi image var.
micro, minimal, standard, ve init.

micro için açıklama şöyle
The ubi-micro is the smallest possible UBI image, obtained by excluding a package manager and all of its dependencies which are normally included in a container image. This minimizes the attack surface of container images based on the ubi-micro image and is suitable for minimal applications, even if you use UBI Standard, Minimal, or Init for other applications. The container image without the Linux distribution packaging is called a Distroless container image.
Açıklaması şöyle
In the following Dockerfile, we utilize the ubi-init (multi-service) image, which supports systemd and has the CMD /sbin/init as the default to start the systemd init service. 
Şöyle yaparız
FROM ubi8/ubi-init

ARG ADMIN_PUBLIC_KEY
ARG TESTER2_PUBLIC_KEY

RUN yum -y install openssh-server openssh-clients 
  && yum clean all && systemctl enable sshd;
...
EXPOSE 2022

CMD ["/sbin/init"]
Örnek - service komutunu kullanan Ubuntu
Şöyle yaparız. Burada ssh için "UsePAM yes" kullanılıyor.
#Bring OS
FROM ubuntu

# Create a user and group that is used to launch processes
# The user ID 1000 is the default for the first "regular" user on Fedora/RHEL,
# so there is a high chance that this ID will be equal to the current user
# making it easier to use volumes (no permission issues)
RUN groupadd -r jboss -g 1000 && useradd -u 1000 -r -g jboss -m -d /opt/jboss -c "JBoss user" jboss && \
    chmod 755 /opt/jboss


# Set the working directory to jboss user's home directory
WORKDIR /opt/jboss

# Install SSH Server, JDK 17
RUN apt-get update && apt-get install -y \
    sudo \
    curl \
    openssh-server \
    openssh-client \
    openjdk-17-jdk && apt-get clean all


# Set passwords
RUN echo root:login-1 | chpasswd
RUN echo jboss:login-1 | chpasswd

# Set the JAVA_HOME variable to make it clear where Java is located
ENV JAVA_HOME /usr/lib/jvm/java-1.17.0-openjdk-amd64

##Install Wildfly
# Set the WILDFLY_VERSION env variable
ENV WILDFLY_VERSION 25.0.0.Final
ENV WILDFLY_SHA1 238e67f48f1bd1e79f2d845cba9194dcd54b4d89
ENV JBOSS_HOME /opt/jboss/wildfly

ADD docker/ubuntu/start.sh /
RUN chmod +x /start.sh

# Add the WildFly distribution to /opt/jboss, and make jboss user the owner of the extracted tar content
# Make sure the distribution is available from a well-known place
RUN cd $HOME \
    && curl -L -O https://github.com/wildfly/wildfly/releases/download/$WILDFLY_VERSION/wildfly-$WILDFLY_VERSION.tar.gz \
    && sha1sum wildfly-$WILDFLY_VERSION.tar.gz | grep $WILDFLY_SHA1 \
    && tar xf wildfly-$WILDFLY_VERSION.tar.gz \
    && mv $HOME/wildfly-$WILDFLY_VERSION $JBOSS_HOME \
    && rm wildfly-$WILDFLY_VERSION.tar.gz \
    && chown -R jboss:0 ${JBOSS_HOME} \
    && chmod -R g+rw ${JBOSS_HOME}

# Create folders for batch processing
RUN bash -c 'mkdir -p /advdata/TspFt/BatchProcessingRoot/rwbat/{input,tmp,output,classicInput,classicTmp,classicOutput}'
RUN chown -R jboss /advdata/TspFt/BatchProcessingRoot/rwbat/

# Ensure signals are forwarded to the JVM process correctly for graceful shutdown
ENV LAUNCH_JBOSS_IN_BACKGROUND true

USER jboss

# Expose the ports in which we're interested
EXPOSE 22
EXPOSE 8080
EXPOSE 9990


#Deploy local files
ADD  docker/modules/system/layers/base/com /opt/jboss/wildfly/modules/system/layers/base/com/
COPY docker/standalone-full.xml /opt/jboss/wildfly/standalone/configuration
COPY build/libs/rwGuiEar.ear /opt/jboss/wildfly/standalone/deployments/

#Create user on wildfly for management
RUN /opt/jboss/wildfly/bin/add-user.sh admin login-1 --silent

# Run as root
USER root

# Set the default command to run on boot
CMD ["/start.sh"]
start.sh şöyledir
service ssh restart

# This will boot WildFly in standalone mode and bind to all interfaces
sudo -u jboss /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0 -c standalone-full.xml


Bean Validation @GroupSequence Anotasyonu

Örnek Elimizde şöyle bir kod olsun public class SampleRequest {   @NotNull   LocalDate startDate;   @NotNull   LocalDate endDate;   @AssertT...