Dependency Injection dla zdalnego klienta

0

Czy jest możliwe posłużenie się dependency injection dla zdalnego klienta? Gdybym chciał np. pobrać jakieś EJB z servera do mojego rozproszonego klienta (application client) nie przez InitialContext ?
Testuje to ale mi nie wychodzi i stad moje pytanie.
W moim kliencie wpisuję anotacji:
@ejb
private nazwa_interfejsu myEJB;
lub
@Resource
private ConnectionFactory connectionFactory;
@Resource
private DataSource baza_danych;
ale to nie działa. Zresztą wydaje mi się że nie powinno działać bo klient zdalny mógłby ewentualnie mieć coś wstrzykniete dopiero po dokonaniu połączenia z serverem a to następuje standardowo przy inicjowaniu obiektu InitialContext.
Wiec jak jest z tym wstrzykiwaniem zależności ?
Nie mogę się tego jakoś doczytać w dokumentacji.

0

Jakbyś doczytał to byś wiedział że takie wstrzykiwanie działa tylko dla klienta lokalnego i jest to bardzo wyraźnie napisane w dokumentacji tam gdzie są te adnotacje opisane.

0
Shalom napisał(a)

Jakbyś doczytał to byś wiedział że takie wstrzykiwanie działa tylko dla klienta lokalnego i jest to bardzo wyraźnie napisane w dokumentacji tam gdzie są te adnotacje opisane.

Gdzie ty to niby przeczytałeś?

http://docs.oracle.com/javaee/6/api/javax/ejb/EJB.html

Indicates a dependency on the local, no-interface, or remote view of an Enterprise JavaBean.

http://docs.oracle.com/javase/6/docs/api/javax/annotation/Resource.html

0

No tak, za pomoca @ejb mozna wstrzyknac remote EJB, ale wszystko musi odbywac sie w jakims kontenerze (EJB, servlet, Application Client Container) a mi sie wydaje ze OP ma na mysli cos innego, i rowniez Shalom mial to samo na mysli.

0

Tak, chodziło mi o zdalnego klienta na zdalnym komputerze (inna maszyna wirtualna). Czyli nie można dokonać takiego wstrzyknięcia. Dzięki.

0

No ale jak ty sobie to wyobrażasz? Że jakoś magicznie twoja aplikacja albo serwer aplikacyjny wykminią sobie gdzie jest ten zdalny obiekt? o_O Nie przyszło ci do głowy że skoro nigdzie nie specyfikujesz adresu jndi i nazwy obiekty to nie bardzo można go odszukać? ;]

0

Widziałem częściowe przykłady kodu klient z użyciem wstrzykiwania tylko nie były opisane jako lokalne. Myślałem że początek, rozpoczęcie sesji jest pominięte specjalnie bo opiera się na pobraniu zwykłego InitialContext(Properties prop) (patrz mój pierwszy post). Dlatego tworząc swoją formułkę klienta dopisywałem sobie tą inicjacje InitialConetxt na samym początku. Nie działało, więc pomyślałem że jakoś inaczej inicjuje się dla wstrzykiwania połączenie z serwerem. Nic nie znalazłem w sieci o tym wiec zapytałem na forum.
Zmylił tez mnie nacisk jaki w materiałach które czytałem autorzy kładli na Dependcy Injection. Wydawało się, że to wielki postęp a wyszło jak zawsze, tylko klient lokalny : )

0

Nacisk kładli bo EJB mimo tego że można je uruchamiać na zdalnym serwerze, w praktyce często jednak uruchamia się na tym samym serwerze co aplikacje które z tych EJB korzystają i wtedy to DI ułatwia trochę życie.

0

W aplikacji SE nie masz nawet anotacji EJB dostepnej, to raz.
DI w EJB 3 dziala Ok, a od kiedy jest CDI (Java EE 6) jest juz calkiem niezle (ale nie idealnie jak dla mnie - czekam na CDI 1.1 / 2.0).

Ja np. problem kiedys rozwiazalem tak - w kliencie SE uzylem Google Guice, napisalem sobie adnotacje typu @MyEJB z atrybutem value ktory jest nazwa EJB ktore chce wstrzyknac, napisalem sobie providera ktory wczytuje plik propeties z ustawieniami JNDI, i umie zczytac z injection point nazwe EJB ktore chce miec, wykonuje lookup i zwraca ta instancje. Nastepnie, w module guice dodaje binding anotacji to providera w scopie jaki chce i juz. Zadna magia, a dziala swietnie. Spwing to umie albo mozna samemu dodac jakies wlasne BeanFactory czy cos, a Weld (JBossowa implementacja CDI dla Javy SE) rowniez na to pozwala. Weld moze nawet ma wtyczki do tego, poszukaj cos o Seam Solder.

0

Ja np. problem kiedys rozwiazalem tak - w kliencie SE uzylem Google Guice, napisalem sobie adnotacje typu @MyEJB z atrybutem value ktory jest nazwa EJB ktore chce wstrzyknac, napisalem sobie providera ktory wczytuje plik propeties z ustawieniami JNDI, ...

Fajne rozwiązanie. Ogólnie wiem o co chodzi ale nie jestem jeszcze tak zaawansowany aby to dokładnie odtworzyć. : )

Nacisk kładli bo EJB mimo tego że można je uruchamiać na zdalnym serwerze, w praktyce często jednak uruchamia się na tym samym serwerze co aplikacje które z tych EJB korzystają i wtedy to DI ułatwia trochę życie.

O takim rozwiązaniu nie pomyślałem. Ale w tym przypadku każdy użytkownik musi mieć u siebie zainstalowany sever aplikacji co obciąża system jak diabli. A z tego co wiem o kliencie lokalnym to aby został uruchomiony na maszynie wirtualnej servera to musi na niej zostać zdeployowany jako specjalny katalog war i wtedy korzystanie z tego klienta przez przeglądarkę z konsoli serwera, bez własnego interfejsu?

0

Nie rozumiem ostatniego zdania, napisz je po polsku. Nie bardzo rozumiem o co ci chodzi bo przecież EJB potrzebują do działania serwera aplikacyjnego. Ja rozumiem że skoro jest podział na klienta i serwer to nie są one mapowane 1:1, bo to by było bez sensu.

0

Mi sie wdaje ze on chce na kliencie odpalic serwer aplikacji, tam napisac jakas aplikacje i wstrzykac remote EJB z innego serwera - nie tedy droga. Musisz albo znalezc takie rozwiazanie jak opisalem powyzej, albo sam je napisac - aplikacje klienckie SE nie maja DI i wstrzykiwania EJB bez dodatkowych bibliotek (na razie?).

0

Shalom chyba źle zrozumiałem (zinterpretowałem) twoje zdanie:

Nacisk kładli bo EJB mimo tego że można je uruchamiać na zdalnym serwerze, w praktyce często jednak uruchamia się na tym samym serwerze co aplikacje które z tych EJB korzystają i wtedy to DI ułatwia trochę życie.

Wyobraziłem sobie sytuacje że każdy użytkownik ma u siebie, na własnym stanowisku, zainstalowany serwer aplikacji w którym ma załadowane potrzebne EJB. Użytkownik loguje się do swojego serwera jako użytkownik lokalny (czyli zdeployowany użytkownik na tym serwerze bo chyba tak się tworzy lokalnego?) i dzięki temu może korzystać z EJB na swoim serwerze przez wstrzyknięcia. Dopiero te EJB (lokalne) łączą się z głównym serwerem (zewnętrznym) przez zwykłe pobranie JNDI i korzystają z EJB umieszczonych na serwerze zdalnym aby wykonać konkretne zadania i pobrać jakieś dane.
Chyba trochę się zagalopowałem.
Pytanie tylko z mojego poprzedniego postu dotyczy klienta lokalnego. Z tego co widziałem w przykładach deployuje sie go na serverze aplikacji (przykład dla JBoss) jako katalog war. Potem chyba używa się z konsoli przez przeglądarkę?
W tym przypadku (jak sądzę) dla klienta lokalnego nie można zrobić jego własnego interfejsu graficznego (ramki z przyciskami) aby ułatwić mu używanie danych EJB?

0

Mozna zrobic klientagraficznego w Javie SE i korzytac z EJB. Musisz znac ustawienia serwera, stworzyc kontenxt JNDI z tymi ustawieniami, znac nazwy beanow ktore chcesz uzywac i je za pomoca lookup pobierac. To reczne rozwiazanie.
Rozwiazanie z DI polega na zaprzegnieciu frakeworka DI ktory albo takie cos ma w standardzie, albo pozwala latwo samemu to napisac. Czyli to co opisalem wczesniej.

0

@Pierce111 źle zrozumiałeś ;]
Zwykle z EJB korzysta jakaś inna aplikacja serwerowa, na przykład aplikacja webowa do której użytkownik ma dostęp przez przeglądarkę. Taka aplikacja webowa często stoi na tym samym serwerze co EJB więc można spokojnie w ramach jednego serwera aplikacyjnego (i jednej Enterprise Application) zrobić takie wstrzyknięcie.

W przypadku klienta desktopowego pozostaje ci tylko wstrzykiwanie za pomocą zewnętrznych mechanizmów typu Guice czy Spring.

0

@Shalom No właśnie. Ale ogólne zasady współdziałania EJB z apliakcjami to znam. W każdym razie dzięki.

@mućka Odnośnie tego klienta (pytam hipotetycznie), z wykonaniem takiego klienta zdalnego nie maiłabym problemu, wszystko tak jak piszesz. Ale przy lokalnym widzę problem (może czegoś nie zakumałem). Lokalny musi być związany z serwerm aby był odpalony na jego maszynie wirtualnej. Jeżeli stworze jakikolwiek interfesj graficzny (UI) w JSE to aby on zadziałał pod maszyna wirtualną serwera to musi być odpalony przez ten serwer. Kod UI musi się zawierać w kodzie klienta. Klient dla JBossa to plik .jsp umieszczany w katalogu np client.war. Nie wiem czy działałeś kiedyś na JBoss 5, jak nie to odpuść sobie to co napisze niżej bo szkoda czasu. Jeżeli jednak tak to popatrz na ten przykład a może znajdziesz błąd bo ja nie wiem co robię źle.
Tworzę wiec plik prostego klienta loklanego (.jsp) o treści żądającej stworzenie pustej ramki :

 <%@page contentType="text/html"
 import="javax.swing.*"
 %>

<%
   
		EventQueue.invokeLater(new Runnable () {
			public void run() {
			JFrame frame = new JFrame("MyRamka");
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setSize(300, 200);
			frame.setVisible(true);
			
			}
			
		});
		
%> 

Serwer deployuje sobie ten plik ale oczywiście żadna ramka sie nie pojawia bo to jest tylko deployment. Teraz ten klient powinien być dostępny z przegladarki pod adresem konsoli:

http://localhost:8080/client/client.jsp

Jak próbuje go uruchomić w ten sposób to dostaję jednak błąd. Normalnie potrafię z wyrzuconego Exception wyczytać co jest nie tak ale tutaj nie jest to dla mnie jasne i wygląda jakby elementy graficzne były zabropnine do uruchamiania w kodzie klienta lokalnego. Oto ten komunikat z okna przeglądarki:

type: Exception report
message: description The server encountered an internal error () that prevented it from fulfilling this request.
exception: org.apache.jasper.JasperException: Unable to compile class for JSP:

An error occurred at line: 7 in the jsp file: /client.jsp
EventQueue cannot be resolved
4:
5: <%
6:
7: EventQueue.invokeLater(new Runnable () {
8: public void run() {
9: JFrame frame = new JFrame("MyRamka");
10: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Stacktrace:
org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:92)
org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:330)
org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:439)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:335)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:313)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:300)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:585)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:312)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:322)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:249)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
note The full stack trace of the root cause is available in the JBoss Web/2.1.3.GA logs.

Chyba ten sposób stworzenia interfejsu dla klienta lokalnego nie wypali.

0

No sprawa jest prosta - nie ma importu dla java.awt.EventQueue.
Ale to co robisz jest kompletnie zle. Nawet jesli Ci sie to uruchomi (serwer moze temu zapobiec) to ten interfejs i tak Ci sie nie pokaze, on sie pokaze lokalnie na serwerze! Wydaje mi sie za zanim sie zabierzesz za pisanie z EJB i serwletami to musisz sobie pocyztac o tym co to jest serwer, co to klient, jakie sa miedzy nimi zaleznosci, co znaczy uruchomienie aplikacji swing na serwerze a co na kliencie. Dopiero pozniej powazniejsze rzeczy. I nie mowie tego wcale zlosliwie, kazdy kiedys zaczynal i robil bledy, takie zycie.

0

Dzięki za podpowiedź. To było to. Normalnie Eclipse wymusza na mnie import klas i nie ma z tym problemu. A tutaj zapomniałem.
Pewnie muszę trochę o tym więcej poczytać jak znajdę dobre źródło bo manual do JBossa jest kiepski. Ale akurat ten klient po poprawce zadziałał i pięknie wyświetlił ramkę. Spróbuję ją jeszcze podpiąć pod jakieś EJB przez jakiś przycisk.
Wielkie dzięki.

0

Klient zadzialal bo pewnie jak to piszesz to klient i serwer jest ta sama maszyna. Sprobuj z 2 komputerami to sie zdziwisz.

0

No tak, bo to jest rozwiązanie tylko dla klienta lokalnego. Na drugim komputerze nie powinien działać.

0

Ja nie rozumiem czemu po prostu nie zrobisz klienta webowego, co rozwiązałoby wszystkie takie problemy :) Można robić ładne interfejsy na stronach www, myśle że często ładniejsze niż to co umożliwia swing ;)

0

Chciałem poćwiczyć tego lokalnego żeby na nim wypróbować wstrzykiwanie zależności. Czyli główne clue tego wątku : )

0

A zdajesz sobie sprawe ze taka aplikacja jaka budujesz nie ma najmniejszego sensu? Pisanie aplikacji z EJB ktora uzywa Swinga na serwerze...

0

No o tym to nie wiem. Swing ma być tylko interfejsem ułatwiającym **lokalnemu ** klientowi używanie EJB przez wywoływanie ich metod biznesowych za pomocą buttonów. Robię to dla celów czysto testowych. Jest to jakieś niebezpieczne podejście?

0

Niebezpieczne o tyle ze robisz cos czegos sie nie robi, dlatego nawet jesli ci sie uda, to nie ma to najmniejszej wartosci. Nie robi sie modulow EJB ze swingiem. Nawet w specyfikacji EJB jest zabronione korzystanie z awt, a aplikacja swing bez awt nie istnieje, wiec sam rozumiesz. To co ty robisz to jest jakies niewiadomoco. Przy wlaczeniu zabezpieczen w serwerze taka aplikacja moze nawert potencjalnie nie zadzialac nawet lokalnie.

0

Nie wiedziałem o takim zakazie dla EJB i Swing. Poszukam coś na ten temat.

1 użytkowników online, w tym zalogowanych: 0, gości: 1