7. Sürüm 3: PAM uygulamasının Glassfish uygulama sunucusuna taşınması
OpenEJB mimarisinin [metier] ve [DAO] katmanlarına ait EJB'leri / EclipseLink mimarisinin [metier] ve [DAO] katmanlarına ait OpenEJB katmanlarını bir Glassfish uygulama sunucusunun konteynerine yerleştirmek istiyoruz.
OpenEJB / EclipseLink ile mevcut uygulama
![]() |
Yukarıda, [ui] katmanı, [metier] katmanının uzak arayüzünü kullanmaktadır.
İki farklı yürütme bağlamını test ettik: local ve distant. İkinci modda, [ui] katmanı, [metier] katmanının istemcisiydi; bu katman ise EJB tarafından uygulanıyordu. İstemci ve sunucunun iki farklı JVM'te çalıştığı istemci/sunucu modunda çalışabilmek için, [metier, DAO, jpa] katmanlarını Java Glassfish sunucusu EE üzerine yerleştireceğiz. Bu sunucu NetBeans ile birlikte gelir.
Glassfish sunucusuyla oluşturulacak uygulama
![]() |
- [ui] katmanı, bir Java SE (Standard Edition) ortamında çalışacaktır
- [metier, DAO, JPA] katmanları, bir Glassfish v3 sunucusu üzerinde Java EE (Enterprise Edition) ortamında çalışacaktır
- İstemci, sunucuyla bir TCP/IP ağı üzerinden iletişim kuracaktır. Ağ iletişimi, geliştirici açısından şeffaftır; ancak geliştiricinin, istemci ile sunucunun iletişim kurmak için nesne referansları değil, serileştirilmiş nesneler alışverişinde bulunduğunun farkında olması gerekir. Bu iletişim için kullanılan ağ protokolü RMI (Remote Method Invocation) olarak adlandırılır ve yalnızca iki Java uygulaması arasında kullanılabilen bir protokoldür.
- Glassfish sunucusunda kullanılan JPA uygulaması, EclipseLink olacaktır.
7.1. PAM istemci/sunucu uygulamasının sunucu tarafı ( )
7.1.1. Uygulamanın mimarisi
Burada, Glassfish sunucusundaki EJB3 kapsayıcısı tarafından barındırılacak sunucu kısmını inceleyeceğiz:
![]() |
Buradaki amaç, OpenEJB konteynerinde halihazırda yapılmış ve test edilmiş olanları Glassfish sunucusuna taşımaktır. OpenEJB'in ve genel olarak gömülü EJB konteynerlerinin önemi de budur: bu konteynerler, uygulamayı basitleştirilmiş bir çalışma ortamında test etmemizi sağlar. Uygulama test edildikten sonra, geriye sadece onu hedef sunucuya, bu durumda Glassfish sunucusuna taşımak kalır.
7.1.1.1. NetBeans Projesi
Öncelikle yeni bir NetBeans projesi oluşturalım:
![]() |
- [1], yeni proje
- [2]'te, Maven kategorisini ve [3]'te EJB Modül türünü seçin. Aslında burada, Glassfish sunucusuna ait EJB konteyneri tarafından barındırılacak ve çalıştırılacak bir proje oluşturuluyor.
![]() |
- [4a] düğmesini kullanarak proje klasörünün üst klasörünü seçin veya adını doğrudan [4b] alanına yazın.
- [5]'te projeye bir ad verin
- [6]'te, projenin üzerinde çalıştırılacağı uygulama sunucusunu seçin. Burada seçilen, [Runtime / Servers] sekmesinde görünen sunuculardan biridir; bu örnekte Glassfish v3.
- [7]'te, Java sürümünü seçin: EE.
![]() |
- [1]'te, yeni proje. Bu proje, klasik bir Java projesinden birkaç noktada farklılık gösterir:
- [Other Sources] [2] adlı bir dal otomatik olarak oluşturulur. Bu dalda özellikle [persistence.xml] dosyası bulunur; bu dosya JPA katmanını yapılandırır,
- projeyi derlediğimizde (Build), [3] adlı bir bağımlılık ve [javaee-api-6.0] dosyası görünür. Bu bağımlılık, Glassfish’in EJB konteyneri tarafından çalışma sırasında sağlandığı için provided türündedir.
7.1.1.2. Kalıcılık katmanının yapılandırılması
Kalıcılık katmanının yapılandırılması derken, aşağıdakileri tanımlayan [persistence.xml] dosyasının yazılmasını kastediyoruz:
- kullanılacak JPA uygulaması
- JPA katmanı tarafından kullanılan veri kaynağının tanımı. Bu, Glassfish sunucusu tarafından yönetilen bir JDBC kaynağı olacaktır.
![]() |
Aşağıdaki şekilde ilerlenebilir. Öncelikle, [Runtime / Databases] sekmesinde, [1] veritabanına bir bağlantı oluşturulur:
![]() |
Bu işlem tamamlandıktan sonra, EJB modülü tarafından kullanılan JDBC kaynak 'sini oluşturmaya geçebiliriz:
![]() |
- [1]'te yeni bir dosya oluşturun – bu işlemi yapmadan önce EJB projesinin seçili olduğundan emin olun
- [2]'te, EJB projesini
- [3]'e, [Glassfish] kategorisini seçin
- [4]'te, JDBC adlı bir kaynak oluşturulmak isteniyor
![]() |
- [5]'te, JDBC kaynağının yeni bir bağlantı havuzu kullanacağını belirtin. Hatırlatmak gerekirse, bir bağlantı havuzu, uygulamanın veritabanıyla olan veri alışverişini hızlandırmaya yarayan açık bağlantı havuzudur.
- [6]'te, oluşturulan JDBC kaynağına JNDI adını verin. Bu ad herhangi bir şey olabilir, ancak genellikle jdbc/nom biçimindedir. Bu JNDI adı, [persistence.xml] dosyasında, JPA uygulamasının kullanması gereken veri kaynağını belirtmek için kullanılacaktır.
- [7]'te, oluşturulacak bağlantı havuzuna herhangi bir ad verin
- [8] açılır listesinden, MySQL / dbpam_eclipselink veritabanında daha önce oluşturulan JDBC bağlantısını seçin.
- [9]'te, bağlantı havuzunun özelliklerinin bir özeti bulunur – hiçbir ayarda değişiklik yapılmaz
![]() |
- [10]'e dönüştürülür; burada bağlantı havuzunun birçok özelliğini belirtebiliriz - varsayılan değerleri olduğu gibi bırakırız
- [11]'te, EJB modülü için JDBC kaynağını oluşturma sihirbazı tamamlandıktan sonra, [Other Sources] dalında bir [glassfish-resources.xml] dosyası oluşturulmuştur. Bu dosyanın içeriği şöyledir:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-resource enabled="true" jndi-name="jdbc/dbpam_eclipselink" object-type="user" pool-name="dbpamEclipselinkConnectionPool">
<description/>
</jdbc-resource>
<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="dbpamEclipselinkConnectionPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
<property name="URL" value="jdbc:mysql://localhost:3306/dbpam_eclipselink"/>
<property name="User" value="root"/>
<property name="Password" value=""/>
</jdbc-connection-pool>
</resources>
[glassfish-resources.xml] dosyası, sihirbaz tarafından toplanan tüm verileri içeren bir XML dosyasıdır. Bu dosya, EJB modülünün Glassfish sunucusuna dağıtımı sırasında, NetBeans tarafından bu modülün ihtiyaç duyduğu JDBC kaynağının oluşturulmasını talep etmek için kullanılacaktır.
Artık, EJB modülünün JPA katmanını yapılandıracak olan [persistence.xml] dosyasını oluşturabiliriz:
![]() |
- [1]'te yeni bir dosya oluşturun – bu işlemi yapmadan önce EJB projesinin seçili olduğundan emin olun
- [2]'te, EJB projesi
- [3]'te, [Persistence] kategorisi seçilir
- [4]'te, bir kalıcılık birimi oluşturmak istiyoruz
![]() |
- 'den [5]'e bir kalıcılık birimi oluşturmak istiyoruz, kalıcılık birimine
- [6]'te, JPA gibi birkaç uygulama önerilir. Burada [EclipseLink]'i seçin. Bu uygulamaları gerçekleştiren kütüphaneleri Glassfish sunucusundaki kütüphanelerle birlikte kurmak şartıyla, diğer uygulamalar da kullanılabilir.
- [7] açılır listesinden, az önce oluşturulan JDBC [jdbc/dbpam_eclipselink] veri kaynağını seçin.
- [8]'te, işlemlerin EJB konteyneri tarafından yönetildiğini belirtin
- [9]'te, EJB modülünün sunucuya dağıtımı sırasında veri kaynağı üzerinde herhangi bir işlem yapılmaması gerektiğini belirtin. Nitekim, EJB modülü, önceden oluşturulmuş bir [dbpam_eclipselink] veritabanını kullanacaktır.
- Sihirbazın sonunda, [persistence.xml] adlı bir dosya oluşturulmuştur. İçeriği şöyledir:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="mv-pam-ejb-metier-dao-eclipselinkPU" transaction-type="JTA">
<jta-data-source>jdbc/dbpam_eclipselink</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
- 3. satır: [mv-pam-ejb-metier-dao-eclipselinkPU] kalıcılık biriminin adı ve işlem türü (JTA, EJB kapsayıcısı için)
- 5. satır: Kalıcılık katmanı tarafından kullanılan veri kaynağının adı JNDI: jdbc/dbpam_eclipselink
- 6. satır: JPA varlıklarının adı belirtilmemiştir. Bu varlıklar, EJB modülünün Classpath'inde aranacaktır.
- Kullanılan JPA (Hibernate, EclipseLink, ...) uygulamasının adı belirtilmemiştir. Bu durumda, Glassfish v3 varsayılan olarak EclipseLink'i kullanır.
7.1.1.3. [jpa, DAO, metier] katmanlarının eklenmesi
[persistence.xml] dosyası tanımlandığına göre, artık [pam] kurumsal uygulamasının [metier, dao, jpa] katmanlarını projeye ekleyebiliriz:
![]() |
Bu üç katman, OpenEJB'teki halleriyle aynıdır. İki proje arasında basit bir kopyala/yapıştır işlemi gerçekleştirilebilir. Şimdi bunu yapacağız:
![]() |
- [1]'te, [mv-pam-openejb-eclipselink] projesindeki [jpa, dao, metier, exception] paketlerinin EJB modülüne kopyalanmasının sonucu [mv-pam-ejb-metier-dao-jpa-eclipselink]
7.1.1.4. Glassfish sunucusunun yapılandırılması
Glassfish sunucusunu iki noktada yapılandırmamız gerekiyor:
- JPA katmanı, EclipseLink tarafından uygulanmaktadır. Glassfish sunucusunun bu uygulama olan JPA'e ait kütüphanelere sahip olduğundan emin olmalıyız.
- Veri kaynağı bir MySQL veritabanıdır. Glassfish sunucusunda bu SGBD için JDBC sürücüsünün bulunduğundan emin olmalıyız.
EJB modülünü devreye alırken bu kütüphanelerin eksik olduğu fark edilebilir. Glassfish sunucusuna eksik kütüphaneleri eklemek için kullanılabilecek yöntemlerden biri şöyledir:
![]() |
- [1]'e dönüştürün, Glassfish sunucusunun özelliklerini görüntüleyin
- [2]'te, sunucunun etki alanları klasörünü not edin. Buna daha sonra <domains>
- <domains>\domain1\lib klasörüne eksik kütüphaneleri yerleştirin. Örnekte, Hibernate kütüphaneleri (lib / hibernate-tools) ve MySQL sürücüsü (lib / divers) eklenmiştir. Varsayılan olarak, Glassfish sunucusunda EclipseLink kütüphaneleri mevcuttur. Bu nedenle, yalnızca MySQL'in JDBC sürücüsü eklenecektir.
![]() |
- [1]'e dönüştürürken, [Services] sekmesinde Glassfish v3 sunucusunu başlatıyoruz
- [2]'te, sunucu aktif hale gelir
7.1.1.5. EJB modülünün dağıtımı
Şimdi EJB modülünü Glassfish sunucusuna dağıtıyoruz:
![]() |
- [1]'te, EJB modülü
- [2]'e, Glassfish sunucusunun dizin yapısı yenilenir
- [3]'e, dağıtımdan sonra EJB modülü Glassfish sunucusunun [Applications] dalında görünür
- [4]'te, JDBC [jdbc / dbpam_eclipselink] kaynağı Glassfish sunucusunda oluşturulmuştur. Bu kaynağı 7.1.1.2. paragrafında tanımladığımızı hatırlatırız.
Dağıtım sırasında, Glassfish sunucusu konsola ilginç bilgiler kaydeder:
3, 6, 8 ve 11. satırlarda
- 3, 6, 8 ve 11'de, dağıtılan JNDI ve EJB'in taşınabilir adları göze çarpmaktadır. Java EE 6, taşınabilir ad kavramını getirmiştir. Bu, tüm Java EE 6 sunucuları tarafından tanınan bir JNDI adını ifade eder. Java EE 5 sürümünde ise JNDI adları, kullanılan sunucuya özeldir.
- 4, 7, 9, 12: Glassfish v3'e özgü bir biçimde dağıtılan JNDI modüllerinin adları.
Bu adlar, dağıtılan EJB modülünü kullanmak üzere yazacağımız konsol uygulaması için faydalı olacaktır.
7.2. Konsol istemcisi - sürüm 1
Artık istemci/sunucu uygulamamızın sunucu tarafını dağıttığımıza göre, [1] istemci tarafını incelemeye geçiyoruz:
![]() |
7.2.1. İstemci projesi
[Java Application] türünde, [mv-pam-client-ejb-metier-dao-eclipselink] adlı yeni bir Maven projesi oluşturuyoruz:
![]() |
- [1]'te, müşteri projesinde
[pom.xml] dosyasına aşağıdaki bağımlılıkları ekliyoruz:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>istia.st</groupId>
<artifactId>mv-pam-client-ejb-metier-dao-eclipselink</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mv-pam-client-ejb-metier-dao-eclipselink</name>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<url>http://download.eclipse.org/rt/eclipselink/maven.repo/</url>
<id>eclipselink</id>
<layout>default</layout>
<name>Repository for library Library[eclipselink]</name>
</repository>
<repository>
<url>http://repo1.maven.org/maven2/</url>
<id>swing-layout</id>
<layout>default</layout>
<name>Repository for library Library[swing-layout]</name>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.appclient</groupId>
<artifactId>gf-client</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mv-pam-ejb-metier-dao-eclipselink</artifactId>
<version>${project.version}</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>org.swinglabs</groupId>
<artifactId>swing-layout</artifactId>
<version>1.0.3</version>
</dependency>
</dependencies>
</project>
- 31-35. satırlar: Bir Classfish istemcisinin uzak bir sunucuyla iletişim kurmasını sağlayan [gf-client] kütüphanesine bağımlılık,
- 36-41. satırlar: EJB modülünün Maven projesine bağımlılık. Burada, JPA varlıklarının tanımlarını, çeşitli arayüzlerin tanımlarını ve [PamException] istisna sınıfının tanımını almak istiyoruz,
[mv-pam-openejb-eclipselink] projesinden [MainRemote] sınıfını kopyalıyoruz:
![]() |
[MainRemote] sınıfı, [metier] katmanındaki EJB sınıfına bir referans almalıdır. [MainRemote] sınıfının kodu şu şekilde değişir:
// tamam - maaş bordrosunu isteyebiliriz
FeuilleSalaire feuilleSalaire = null;
IMetierRemote metier = null;
try {
// Glassfish sunucusunun JNDI bağlamı
InitialContext initialContext = new InitialContext();
// iş mantığı katmanının örneklenmesi
metier = (IMetierRemote) initialContext.lookup("java:global/istia.st_mv-pam-ejb-metier-dao-eclipselink_ejb_1.0-SNAPSHOT/Metier!metier.IMetierRemote");
// maaş bordrosu hesaplaması
feuilleSalaire = metier.calculerFeuilleSalaire(args[0], nbHeuresTravaillées, nbJoursTravaillés);
} catch (PamException ex) {
System.err.println("L'erreur suivante s'est produite : "
+ ex.getMessage());
return;
} catch (Exception ex) {
System.err.println("L'erreur suivante s'est produite : "
+ ex.toString());
return;
}
- 6. satır: Glassfish sunucusunun JNDI bağlamının başlatılması.
- 8. satır: Bu JNDI bağlamından, [metier] katmanının uzak arayüzüne ilişkin bir referans talep edilir. Glassfish günlüklerine göre, [metier] katmanının uzak arayüzünün iki olası adı olduğu bilinmektedir:
- satırda, tüm uygulama sunucularıyla kullanılabilen JNDI adı: JAVA, EE, 6. 2. satırda ise Glassfish'e özgü JNDI adı. Kodda, 9. satırda, taşınabilir JNDI adını kullanıyoruz.
- Kodun geri kalanında değişiklik yok
![]() |
[1]'te, projeyi [MainRemote] sınıfını argümanlarla çalıştıracak şekilde yapılandırıyoruz. Her şey yolunda giderse, projenin çalıştırılması şu sonucu verir:
Özellikler bölümüne yanlış bir sosyal güvenlik numarası girilirse, şu sonuç elde edilir:
7.3. Konsol istemcisi - sürüm 2
Önceki sürümlerde, Glassfish sunucusundaki JNDI ortamı, proje arşivlerinin bir yerinde bulunan [jndi.properties] dosyası kullanılarak yapılandırılıyordu. Bu dosyanın varsayılan içeriği şöyledir:
# Sun Application Server'a erişim JNDI
java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory
java.naming.factory.url.pkgs=com.sun.enterprise.naming
# CosNaming için bir javax.naming.spi.StateFactory eklenmesi gerekir; bu
# dinamik RMI-IIOP'i destekler.
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl
org.omg.CORBA.ORBInitialHost=localhost
org.omg.CORBA.ORBInitialPort=3700
- ve 8. satırlar, JNDI hizmetinin çalıştığı makineyi ve bu hizmetin dinleme bağlantı noktasını belirtir. Bu dosya, localhost dışındaki bir JNDI sunucusuna veya 3700 bağlantı noktası dışındaki bir bağlantı noktasında çalışan bir sunucuya sorgu yapılmasına izin vermez. Bu iki parametreyi değiştirmek istersek, kendi [jndi.properties] dosyamızı oluşturabilir veya bir Spring yapılandırması kullanabiliriz. Biz bu ikinci tekniği göstereceğiz.
İlk olarak, başlangıçtaki [pam-client-metier-dao-jpa-eclipselink] projesinden yeni bir proje oluşturuyoruz.
![]() |
- [1], yeni proje
- [2], Spring yapılandırma dosyası [spring-config-client.xml]. İçeriği şu şekildedir:
Spring yapılandırma dosyası şöyledir:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<!-- meslek -->
<jee:jndi-lookup id="metier" jndi-name="java:global/istia.st_mv-pam-ejb-metier-dao-eclipselink_ejb_1.0-SNAPSHOT/Metier!metier.IMetierRemote">
<jee:environment>
java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory
java.naming.factory.url.pkgs=com.sun.enterprise.naming
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl
org.omg.CORBA.ORBInitialHost=localhost
org.omg.CORBA.ORBInitialPort=3700
</jee:environment>
</jee:jndi-lookup>
</beans>
Burada Spring 2.0 ile ortaya çıkan bir <jee> etiketini (14. satır) kullanıyoruz. Bu etiketin kullanımı, ait olduğu şemanın tanımlanmasını gerektirir (4., 10. ve 11. satırlar).
- 14. satır: <jee:jndi-lookup> etiketi, JNDI hizmetinden bir nesnenin referansını almayı sağlar. Burada, "metier" adlı bean, EJB ve [Metier] ile ilişkili JNDI kaynağına eşleştirilmektedir. Burada kullanılan JNDI adı, EJB'in taşınabilir adıdır (Java 6).
- [jndi.properties] dosyasının içeriği, JNDI hizmetine bağlantı parametrelerini tanımlamak için kullanılan <jee:environment> etiketinin içeriği (15. satır) haline gelir.
Ana sınıf [MainRemote] şu şekilde değişir:
7-8. satırlarda, [metier] katmanındaki [IMetierRemote] tür referansı Spring'den istenir. Bu çözüm, mimarimize esneklik kazandırır. Nitekim, [metier] katmanındaki EJB yerel hale gelirse, c.a.d. [MainRemote] istemcimizle aynı JVM'te çalıştırılsa bile, istemcimizin kodu değişmez. Yalnızca [spring-config-client.xml] dosyasının içeriği değişecektir. Böylece, 5.11. paragrafta incelenen Spring / JPA mimarisine benzer bir yapı elde edilecektir.
Okuyucunun bu yeni sürümü denemesi önerilir.
7.4. Swing istemcisi
Şimdi, EJB adlı istemci/sunucu uygulamamızın swing istemcisini oluşturuyoruz.
![]() |
[pom.xml] dosyası, Swing uygulamaları için gerekli bağımlılıklara sahip olmalıdır:
<dependency>
<groupId>org.swinglabs</groupId>
<artifactId>swing-layout</artifactId>
<version>1.0.3</version>
</dependency>
Yukarıda, [PamJFrame] sınıfı başlangıçta Spring / JPA ortamında çalışmak üzere yazılmıştı:
![]() |
Şimdi bu sınıf, Glassfish sunucusunda dağıtılmış bir EJB sınıfının uzak istemcisi haline gelmelidir.
![]() |
Uygulama alıştırması: Projedeki [ui.console.MainRemote] konsol istemcisi örneğini takip ederek, [doMyInit] (bkz. paragraf 5.12.4) tarafından kullanılan yöntemi değiştirin ve artık uzak olan [metier] katmanına bir referans alın.

























