Problem z konfiguracją frameworka Weld

0

Witam.
Próbuje napisać prostą aplikację w frameworku Weld z wykorzystaniem Mavena. Do pom.xml dodałem najnowszą bibliotekę 3.0.1.Final, plik bean.xml jest opatrzony podstawowymi znacznikami. Aplikacja składa się z kilku komponentów wzajemnie od siebie zależnych i klasy z metodą main, która je wykorzystuje (Obiekty, które mają być wstrzyknięte oznaczone są adnotacją @Inject i są opatrzone konstruktorami). Na pierwszy rzut oka aplikacja działa, obiekty są inicjalizowane przez kontener, lecz w logach pojawia się następująca informacja:

INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.

**Dodatkowo to co zauważyłem to fakt, że czas wstrzykiwania jest strasznie długi. **
Czy ktoś może spotkał się z takim problemem? Na stackoverflow natrafiłem na artykuł: https://stackoverflow.com/questions/24705017/weld-not-initializing-properly.
Z tego co jest tam napisane w ostatnim komentarzu, teoretycznie powinno to działać...

Program główny ma postać:

Weld theWeld = new Weld();
 WeldContainer theContainer = theWeld.initialize();
Component component = (Component)  theContainer.instance().select(Component.class).get();

Proszę o jakieś wskazówki.
Pozdrawiam

0

Nie bardzo rozumiem w czym problem. Przecież to działa. Że nie ma tam JTA to akurat nie dziwota skoro odpalasz standalonową aplikacje z gołym Weldem. A że czas inicjalizacji kontenera jest długi, ot tak juz mają ze chwile startują.

0

Właśnie tu chodzi głównie o czas pobierania beana. Czas startu jest całkiem niewielki 20ms (Czas pobrania beana - miliona elementów za pomocą metody weld.select(Component.class).get() to już 700ms, gdzie w Springu było to 60ms).

Dlatego uważam, że coś może być jeszcze na rzeczy z konfiguracją.

1

A jak wyglądaja te klasy które wstrzykujesz? Bo jeśli to są POJO to bardzo mozliwe że Weld traktuje je jako Beany EJB a nie jako Beany CDI, co dodaje pewien narzut na operacje z nimi związane. Zobacz co się stanie jeśli dorzucisz do tych klas adnotacje @ApplicationScoped albo @Named.

0

Rzeczywiście to chyba najbardziej prawdopodobny scenariusz. Sprawdzę to po południu, jak tylko będę miał dostęp do kodu.

0

Czas pobrania beana - miliona elementów za pomocą metody weld.select(Component.class).get() to już 700ms

Możesz doprecyzować, o co chodzi z tym milionem? Czy czas pobierania kolejnych beanów jest krótszy?

Edit: mierzyłeś czas łącznie z wywołaniem instance() czy osobno?

0
  1. Chciałem sprawdzić ile czasu zajmie pobranie milion razy jednego beana z kontenera (Mierzony jest czas jedynie wywołania metody pobierającej komponent). Jeżeli potem odwołuje się do innych beanów, to problem jest ten sam (Długi czas otrzymania konkretnego obiektu).

  2. Chodzi o wywołanie **container.instance().select(Component.class).get() **? Jeżeli tak, to próbowałem także pobierać komponent w ten sposób i efekt jest ten sam.

1

Spring ma zdaje się domyślny scope singleton. Weld może ma prototype. I to by wyjaśniało. Zadeklaruj jawnie scope (singleton albo application) i wtedy porównaj. Czyli rada Shaloma.

700 ms dzielone na milion, to jakiś trudny w ogóle do wyliczenia czas. 0,7 mikrosekundy. Trochę nie rozumiem, jak wykryłeś, że to stanowi problem w aplikacji. Czas obsługi żądania http jest rzędu milisekund, jak te pojedyncze mikrosekundy mają zaburzyć działanie aplikacji?

0
ralf2005 napisał(a):
  1. Chciałem sprawdzić ile czasu zajmie pobranie milion razy jednego beana z kontenera (Mierzony jest czas jedynie wywołania metody pobierającej komponent). Jeżeli potem odwołuje się do innych beanów, to problem jest ten sam (Długi czas otrzymania konkretnego obiektu).

Jak będziesz chciał każdy obiekt w aplikacji robić jako bean to rzeczywiście może być problem.
Ale może warto robić beanami tylko te najważniejsze, fasady?

0
  1. Dokładnie Spring działa na Singletonach. Próbowałem oznaczać wstrzykiwane beany adnotacją @Singleton, ale nic to nie zmieniło. Mogę to zrobić w jakiś inny sposób?

  2. Chciałem zrobić zestawienie frameworków wykorzystujących DI i każde różnice w czasie będą dla mnie ciekawe. Zastanawia mnie tylko, że Spring, Guice i PicoContainer mieści się w czasie 50-100, a Weld nagle zwrócił wartość z przedziału 700-900. Spróbuje się zastosować do Waszych rad i wieczorem dam odpowiedź, czy coś się zmieniło.

2

Czemu było ukrywać, że robisz benchmarki :)

Wg mnie mierząc milion pobrań tego samego obiektu powinieneś to rozbić na czas pierwszego pobrania i czasy kolejnych.

0

Jak już robisz benchmarki, to fajnie. Podziel się wynikami. Ale sensowny benchmark to taki, w którym masz tysiące beanów zależnych od siebie. Na to zapuszczasz frameworka i mierzysz. Raczej inicjalizację + pojedyncze pobrania, nie miliony. Nie ma obaw, to będzie trwało długo, nie trzeba zwielokratniać. Osobno w 2 kategoriach: setter i constructor injection.

1

Jak już robisz benchmarki w Javie, to mam nadzieję, że przejrzałeś obowiązkowe pozycje czyli np. to video:
https://vimeo.com/78900556 (były lepsze i nowsze wersje - ale nie mogłem na szybko znaleźć).

Nie pamiętam czy kiedyś widziałem nie zrypany benchmark w Javie. Łącznie z moimi :-( Różnice sa tylko takie, że czasami widać bzdurę po 5 sekundach, czasem po minucie, a czasem wychodzi dopiero po miesiącu. Na zrobienie niekórych benchmarków poświęciłem tygodnie... potem i tak znajdowałem błędy.
Największy problem to statystyka - czyli postawienie weryfikowalnej hipotezy, której dodatkowo obronienie lub obalenie ma jakiś sens biznesowy.

Ja strzelam u Ciebie, taką hipotezę: wybór frameworka DI (wśród tych kilku standardowych, znanych) ma nieistotny wpływ na szybkość działania twojej aplikacji. Tu założenie jest takie , ze nie piszesz czegoś chorego. Bo (tak jak niejako napomknąl @vpiotr) nawet jak piszesz w Spring czy innym badziewiu - normalnie jedynie pewna mała częśc twoich klas to beany.

0

Witam. Niestety adnotacje @ApplicationScoped lub @named za wiele nie pomogły. Dalej czasy są większe niż 700ms, oraz jest wyświetlany na konsoli poniższy błąd:

INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.

Ktoś może ma jeszcze jakieś pomysły? Może to wina biblioteki? Niby weld.se wspiera CDI. Już w sumie skończyły mi się pomysły.

1

Z moich testów przeprowadzonych na najnowszym WebLogicu wynika, że Weld pobiera 1000000 takich samych obiektów w około 100 ms. Na starym laptopie Intel Core I3. To by potwierdzało sugestię z tytułu "Problem z konfiguracją frameworka Weld", nie zaś z wydajnością tego frameworka.

Trudno badać konfigurację, albo metodę pomiaru, bez dostępu kodu źródłowego.

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