Zdanek devBlog+

July 17, 2010

Many problems with betterbeansbinding – one solution :)

Filed under: develop, java — Tags: , — zdanek @ 14:39

If your binding expressions contain errors or data sources are not available you can get several warnings from EL resolver. But no one of BBB developers thought about good debbuging feedback in such situations. All you get are some of these


2010-07-17 14:10:24 org.jdesktop.beansbinding.util.logging.Logger log
WARNING: isReadable(): expression is unresolvable

2010-07-17 14:10:24 org.jdesktop.beansbinding.util.logging.Logger log
WARNING: updateCache(): expression is unresolvable

2010-07-17 14:10:26 org.jdesktop.beansbinding.util.logging.Logger log
WARNING: isWriteable(): expression is unresolvable

But where? In which class? What binding expression? Damn it! How could I work with this tool?!

I’ve made very simple changes in CLProperty class of BBB src code. One of them


logger.warning("updateCache(): expression is unresolvable: " +
expression + " for source " + source);

Simple, huh? Now I get


2010-07-17 14:27:10 org.jdesktop.beansbinding.util.logging.Logger log
WARNING: updateCache(): expression is unresolvable: ValueExpression[${rootModel.currentRouteTemplate.inRoutePointTemplates}] for source pl.autoguard.ac21.ptir.mvc.view.TransportRouteView[,0,0,856x612,invalid...

Now I can clearly see that ${rootModel.currentRouteTemplate.inRoutePointTemplates} expression failed for visual element in pl.autoguard.ac21.ptir.mvc.view.TransportRouteView class.

Downloads

Altered ELProperty class.

Altered betterbeansbinding-core-1.3.0b1.jar and betterbeansbinding-core-1.3.0b1.pom (note version 1.3.0b1). This jar should be used instead 1.3.0 version. Update your dependencies today! :)

July 1, 2010

NoClassDefFoundError: org.slf4j.impl.StaticLoggerBinder

Filed under: java, maven — Tags: , , — zdanek @ 10:20

I get error while running code with Hibernate 3.5.x

java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
at org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:223)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:120)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:111)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:269)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:242)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:255)
at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:165)
at org.hibernate.ejb.Ejb3Configuration.<clinit>(Ejb3Configuration.java:127)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:54)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
at pl.bartekzdanowski.MyTest.setUp(MyTest.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:303)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316)
… 43 more

The solution is described on SLF4j page. Simply you have to add slf4j-api with wersion greater than 1.5.6. In maven pom.xml you can declare slf4j explicitly:

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

June 10, 2010

650 na Javarsovię, a rejestracja trwa!

Filed under: java — Tags: — zdanek @ 23:46

Właśnie sprawdziłem statystyki i mamy 653 zapisanych, w tym 33 damy :D

To jakiś madness! Moim zdaniem, nawet jak część nie przyjdzie, to i tak przekroczymy PÓŁ TYSIĄCA! :D

June 3, 2010

Rejestracja na Javarsovia 2010 otwarta!

Filed under: java — Tags: — zdanek @ 20:25

Rejestracja na Javarsovię 2010 jest już otwarta od dwóch dni. Mamy już przeszło 250 zapisanych!

A czy Wy już jesteście zapisani? Bo ja zdaje się widziałem Waszego sąsiada, tego grubszego spod 5tki, że on już zarejestrowany!

Uczestnictwo, dzięki sponsorom, jest bezpłatne, ale wymaga rejestracji.

Możecie sobie poczytać o zgłoszonych prezentacjach, a podczas rejestracji można wybrać 6 preferowanych. Na podstawie wyborów ułożymy 4 ścieżki.

Jeśli już się zarejestrowaliście, ale nie określiliście preferencji rozkładu, to proszę zróbcie to – będzie to dla nas cenną wskazówką.

Wszystko jest mailu potwierdzającym.

Pomóżcie nam promować Javarsovię. Miejcie swój wkład w najwiekszą bezpłatną konferencję Javową w Polsce. Piszcie na blogach, dzwońcie do rodziny, ustawcie statusy na GG itp., wysyłajcie smsy, zaznaczcie swoją obecność na konferencji na LinkedIn i na Facebooku, niech Wasze kontakty wiedzą co się szykuje.

Do dzieła! :D

April 27, 2010

InetAddress.isReachable() jest do bani

Filed under: develop, java — Tags: , — zdanek @ 09:56

Napisałem mały program testujący czy klient “widzi” prawidłowo adres i porty naszego serwera aplikacyjnego. Zdarza się, że Firewalle klientów skutecznie blokują łączność.

Zależało mi, aby w pierwszym kroku “spingować” hosta. Niestety wczoraj odkryliśmy buga, bo polegałem na metodzie InetAddress.isReachable(). Tymczasem sposób jest do chrzanu, bo implementacja nie pinguje a odpytuje usługę echo, która stoi na porcie 7. Wielu adminów blokuje tego typu usługi, starając się maksymalnie uszczelnić serwery. U nas w firmie też i dlatego nasi klienci dostawali informację, że istnieje brak łączności z jednym z serwerów.

Nie dostarczę dzisiaj rozwiązania, z braku czasu, ale wrócę do tematu kiedyś.
Poniżej wadliwy kod:


 final String host = "zdanek.ostrejezyki.pl";
 final int timeOut = 3000;

 final boolean status = InetAddress.getByName(host).isReachable(timeOut);

 if (status == false) {
      throw new IOException("Brak lacznosci z " + host);
 }

April 16, 2010

W końcu logować z IF (isDebugEnabled()) czy nie?!

Filed under: develop, java — Tags: , , — zdanek @ 12:52

Ostatnio staram się pisać małe metody, w imię czytelności kodu. W związku z tym każda dodatkowa linijka zwiększa objętość metody. W malutkich metodach jedna linia to nawet kilkadziesiąt procent objętości :) A co z logowaniem informacji debugujących? Zgodnie z zaleceniami autora Log4j (bo tego loggera zazwyczaj używam), przed zalogowaniem debug() powinno się sprawdzić czy ten poziom jest włączony, aby niepotrzebnie nie tracić czasu procesora na inicjalizowanie stringa do zalogowania. Ceki Gülcü, autor Log4j, w 2002 przekonywał, że sprawdzanie IFem poziomu na PII 233MHz zajmuje nanosekundy, co stanowi mały narzut. Rzeczywiście. A co, gdyby w imię czytelności kodu zrezygnować z tego sprawdzania? Co się wówczas stanie? Ile czasu stracimy? I czy mimo wyłączonego logowania niepotrzebnie wiadomość będzie przetwarzana wewnątrz loggera?

Otóż, oba popularne loggery Log4j i java.utils.Logging sprawdzają czy dany poziom jest włączony i oczywiście nie logują komunikatu, jeśli nie pasuje do poziomu. W takim razie jedynym istotnym problemem jest czas konstruowania wiadomości do zalogowania. Zazwyczaj jest to operacja sklejania kilku stringów, bo chcemy zalogować jakąś operacje np. z jej parametrami. Warto przy tym zauważyć, że czasy kiedy “jakiś string” + “inny” powodowało kilka wywołań konstruktora String(). Od javy 1.5 (lub wcześniej, bo nie wiem) , sklejanie stringów zawsze jest zastępowane StringBuilderem, a więc jest bardzo efektywne. W związku z tym, każdorazowo należy rozważyć czy dany string, który chcemy zalogować jest złożony czy nie. Jeśli nie, to moim zdaniem nie warto stosować IFów, tylko bezwzględnie pchać go loggera.

A teraz konkretne miary, jako, że jestem inżynierem. Test wykonany na procku dual core 2.66GHz, czyli rząd wielkości szybszy od twórcy Log4j. Dzisiaj uważany za przeciętnie dobry sprzęt.
Napisałem program, który 100 000 razy loguje wiadomość, przy wyłączonym debugowaniu. Przy czym w pierwszym teście odbija się od sprawdzenia IFem czy włączone jest debugowanie, a w drugim wchodzi do środka metody logującej. Logowany string to

"Wiadomosc testowa, index " + i + " i jeszcze string"

Mamy tu 3 operacjie StringBuilder.add(), przy czym dla int i jest najbardziej kosztowna, bo i jest od razu zamieniane na string. Wynik:

Test logow bez wlaczonego debuga, ze sprawdzaniem IF
Czas 0ms
Test logow bez wlaczonego debuga, bez sprawdzania IF
Czas 93ms

0 ms oznacza rzeczywiście submilisekundowe czasy sprawdzania czy poziom to DEBUG. 93 ms w rozłożeniu na 100 tyś. wywołań daje nam 93 ns (nano sekund!) na sklejanie. Dodam na koniec, że zaskoczony wynikiem podejrzewałem mocną optymalizację ze strony JVM, czego nie da się wykluczyć, ale drugi test z wielokrotnym powtórzeniem logowanej wiadomości (czyli rezygnacja z pętli) dało również submilisekundowe wyniki. Wkleiłem setkę razy

logger.debug("Wiadomosc testowa, index " + (i++) + " i jeszcze string");

Konkluzja: moim zdaniem przy prostej treści logowanej wiadomości, można zrezygnować ze sprawdzania poziomu logowania na rzecz uproszczenia (wizualnego) kodu.

Źródełko:

package pl.ostrejezyki.zdanek;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class LoggingEffectivenessTests {

    private static Logger logger = Logger.getLogger(LoggingEffectivenessTests.class);

    public static void main(String[] args) {

        initLog4j();

       testCheckingIfDebugIsEnabled();
       testWithoutCheckingIfDebugIsEnabled();

    }

    private static void testWithoutCheckingIfDebugIsEnabled() {
        long start;
        long stop;
        System.out.println("Test logow bez wlaczonego debuga, bez sprawdzania IF");

        start = System.currentTimeMillis();
        for (int i = 0; i &lt; 100000; i++) {
            logger.debug("Wiadomosc testowa, index " + i + " i jeszcze string");
        }
        stop = System.currentTimeMillis();

        System.out.println("Czas " + (stop - start) + "ms");
    }

    private static void testCheckingIfDebugIsEnabled() {
        System.out.println("Test logow bez wlaczonego debuga, ze sprawdzaniem IF");

        long start = System.currentTimeMillis();
        for (int i = 0; i &lt; 100000; i++) {
            if (logger.isDebugEnabled()) {
                throw new IllegalStateException("Debug wlaczony, a powinien byc wylaczony");
            }
        }
        long stop = System.currentTimeMillis();

        System.out.println("Czas " + (stop - start) + "ms");
    }

    private static void initLog4j() {
        Logger l = Logger.getRootLogger();
        ConsoleAppender ca = new ConsoleAppender();
        l.addAppender(ca);
        l.setLevel(Level.ERROR);
    }
}

July 1, 2009

“Cannot allocate memory” while compiling project with maven

Filed under: develop, java, maven — zdanek @ 13:48

While compiling my project with Maven I got sometimes on my Linux (Gentoo actually) box the following error

[ERROR] BUILD ERROR
[INFO] ————————————————————————
[INFO] Error reading assembly descriptors: Error reading descriptor at: /var/www/app_src/src/main/assembly/package.xml: Cannot run program “env”: java.io.IOException: error=12, Cannot allocate memory

This was caused by not enough amount of swap memory on linux. After increasing to double size of physical memory all problems are gone.

I was inspired by this entry of Hudson Wiki.

June 15, 2009

Przyśpiedzanie ładowania testowego Netbeans Platform

Filed under: develop, java, netbeans — zdanek @ 07:52

Dużym problemem podczas tworzenia pluginów Netbeans jest bardzo długi czas ładowania testowej platformy. Przyczyną są wszystkie dodatkowe moduły, które są zainstalowane. Można zmniejszyć liczbę ładowanych modułów o te, które nie są nam potrzebne do testowania naszego pluginu. W zależności od tego czy tworzone moduły uruchamiamy oddzielnie, czy może razem spięte w Module Suite, proponuję dwa rozwiązania.

Dla pojedynczych modułów, po uruchomieniu Netbeans z naszym pluginem, otwieramy listę pluginów i wyłączamy jak leci wszystko po kolei, co tylko nie jest nam potrzebne. Po następnym uruchomieniu Nb będzie ładował się błyskawicznie. Ale, uwaga, zrobienie clean na projekcie kasuje nam wszystkie ustawienia…

Druga metoda jest trwalsza, ale tylko dla Module Suite. Klikamy prawym na naszym Suite i z properties wybieramy libraries. Tam odznaczamy wszystko prócz wymaganych zależności, w tym na pewno zostawiamy klastry platform9 i nb6.5 (obie wersje zależą od wersji Nb).

Ponieważ pozostawione moduły mają zależności do wyłączonych, podczas odpalania Nb zapłacze, że czegoś mu brakuje, ale wystarczy wcisnąć magiczny przycisk i popsute moduły zostaną wyłączone. Czas ładowania takiego Netbeansa to ok 3-4sek. Można jeszcze powyłączać poszczególne pluginy wewnątrz klastrów.

Zwróćcie uwagę, że wszystko co zaznaczycie/odznaczycie zostanie zapisane w pliku platform.properies sekcji Important files.

March 31, 2009

Zdobyłem certyfikat “Netbeans Platform Certified Associate” :

Filed under: java, netbeans — zdanek @ 11:03

W miniony weekend (28-29 III 2009) przeszedłem szkolenie z podstaw Netbean Platform. Szkolenie zorganizowane z ramienia Warszawa JUG, prowadziło dwóch miłych panów z Suna (Geertjan Wielenga i Karol Harezlak), którzy na codzień zajmują się rozwijaniem Netbeansów.

Na koniec szkolenia wszyscy uczestnicy otrzymali certyfikat, który jest pierwszym stopniem wtajemniczenia. W sumie oznacza “liźnięcie” tematu. Dalsza możliwość to Certified Engineer, o który mam zamiar się starać.

Netbeans Platform Certified Associate

Netbeans Platform Certified Associate

Podczas szkolenia zdobyłem też najnowszą książkę Geertjana et al. za najciekawsze pytanie, o czym Geertjan wspomniał na swoim blogu :D

Rich Client Programming: Plugging into the NetBeans Platform

Ciekawostką jest, że Karol jest Polakiem, który od kilku lat pracuje w Pradze dla Suna, przy rozwoju modułu Mobility Netbeansów.

Ekipa szkolenia (ja robiłem zdjęcie)

Ekipa szkolenia (ze mną po środku, bo Łukasz robił zdjęcie ;)

Ekipa szkolenia (ze mną po środku, bo Łukasz robił zdjęcie ;)

February 10, 2009

Crystal Reports java viewer JNDI problem

Filed under: develop, java — Tags: , , , — zdanek @ 19:50

I hate Crystal Reports. We use CR XI and it really sucks. Crystal Reports java library has some awful bugs.

When report viewer is loading there’s some output to stdout:

Crystal Report Viewer 11.8.4.1197
java.vendor = Sun Microsystems Inc.
java.version = 1.6.0_10
os.name = Windows XP
os.version = 5.1
os.arch = x86

Why? Because inside CR classes there’s a direct output to std out and it sucks. But it’s a minor problem.

The worst bug is inside database connection layer, somewhere very deep inside CR java lib. Under an unknown condition sometimes it throws some exceptions with “error finding JNDI name” message. It happens while “switching database”. If you don’t know what’s this, try to dig the net.

The problem is that the reason cannot be defined. The same report sometimes causes this error to appear while another invocation causes nothing bad to happen and the report displays properly.

Workaround

Did I mentioned that Crystal Reports sucks? Oh, yes. As I wrote repeating invocation of a report causes it to display properly. So after two days of debugging and digging throught the Internet with no solution I came to stupid but successful idea.  Repeat tables switching until no error appears. The process doesn’t take too long. It always took only two loops to successful switch. SWITCH_TABLE_RETRIES is limit of tries (mine is set to 3 and it works well).

boolean successSwitch = false;
//Update old table in the report with the new table.
for (int j = 0; j < SWITCH_TABLE_RETRIES; j++) {
    if (successSwitch) {
        if (j > 1 && Logger.getLogger(AbstractReport.class).isDebugEnabled()) {
            Logger.getLogger(AbstractReport.class).debug("Switch tables after tries: " + j);
        }
        break ;
    }

    try {
        databaseController.setTableLocation(t, tables.getTable(i));
        successSwitch = true;
    } catch (final Throwable th) {
        //if it's the last try as we failed
        if (j + 1 == SWITCH_TABLE_RETRIES) {
            Logger.getLogger(AbstractReport.class).error("Switch tables error " + th.getMessage());
        }
    }
}

There’s another bug discovered by some guy and another weird solution.

CR sux :) The end.

And some polish phrases to be indexed by google and help my colleagues to solve the problem.

Błąd podczas znajdowania nazwy JNDI
Problem z Crystal Reports XI
Przeglądarka
Błąd wyświetlania raportu, raportów

Powered by WordPress

WP-Highlight