Category Archives: Tools

Jboss AS Wildfly for Java developer tutorial

How often do You face situation when local development is done using simple Tomcat or Jetty container? Very often backed up with JRebel? Yeah, that’s what I thought 馃槈 It works like a charm but finally there is always an ultimate problem – deployment to dev/integration/prod environment. Why it is an issue? Because usually it is application server we have to deal with. And here comes the problem.

I’ve faced such situation many times. The expected truth is that it should make no difference. Servlet container is also a part of application server. Yes, I can agree to that, but very often there is some kind of a problem during application deployment in application server. If we have always-ready-to-fast-response-admin-team it is no such big deal. But what happens if reality is not so great – and the only thing we have is log file that does not tell us anything? We have a problem for sure. And that is exactly my point. It is better to understand a little bit of our application server. That is the subject of this blog post. I will show how to install and configure local instance of JBoss Wildfly and deploy simple application to it. I do not see this post as comprehensive tutorial – it is just some kind of ‘lessons learned’ to me. Let’s go.

Versioning, terminology and WTH is EAP?

In the good old days everything was simple. There was JBoss Application Server and that was it. I remember when I entered Java world version in use was 4.x one. As years went by I sometimes came across next versions of that server in my contractor’s career, but never paid special attention as I mostly used Weblogic. Some time ago I found out that there is some kind of new kid in town – Wildfly. After a little bit of digging I learned that it as good old Jboss AS but with different name. Why did that happen?

The answer is simple – JBoss Enterprise Application Platform (or for short Jboss EAP) emerged. EAP is a commercial product – it is usually much more ahead with bugfixes that community version of the server. To use it in a production mode you have to pay Jboss. On the other side there is still good old Jboss AS which is now called Wildfly mostly because there was very similar versioning of EAP and JBoss AS. The truth is – if You have EAP used in production (or dev/integration env) and You want to make sure Your app will work there use this site to find out which application’s server version You need and then download it and run. Wildfly is a name for newer version of Jboss AS (starting from version 8) and as far as I can see it, so far it is not yet used in EAP at all.

Despite what I have written above I decided to use latest stable Wildfly in my tutorial. Why? Because as I browsed through latest EAP and Wildfly documentation and folders I see no difference. What is more important – Wildfly can be downloaded ‘by hand’ from its page, with EAP registration is required. And I know for how many people that can be a concern 馃槈 So just download 8.2.0.Final and we can start.

Installation, folder structure and first run

Installing JBoss is fairly easy – just download ZIP archive and unpack it. Piece of cake. Now we can proceed to the unpacked directory to the bin folder. There are files (executables for both Windows and Linux). What should we use? The idea here is to understand the modes in which server can be run. There are two:

a) standalone mode – which is sufficient for 99% of usages on developer’s machines. It does not mean that it is not suitable for production machines. Server running in standalone just run in one process and whole configuration is specific only to this one machine.

b) domain mode – it is mostly used in production environments as it provides way to keep server’s config consistent using just one machine.

Domain mode does not mean clustering! There is no problem to create cluster using both – standalone or domain mode.

In order to understand basic concepts which are important to Java developers I will use standalone mode in this post. My idea is to present domain and clustering in the future. Sometimes I will mention things related to domain mode (in comparison to standalone).

Having said that we concentrate only on bin/standalone.bat executable (I am working on Windows, Linux users should be familiar with .sh scripts). To separate run-scripts from configuration there is additional config file named standalone.conf.bat, that is used by run-script to customize configuration. Usually when there is no previous JBoss (which in fact means there is no global JBOSS_HOME variable set) we need no additional configuration (besides set JAVA_HOME). Before we start the server we can look around bin folder:

a) adduser.bat – adds user to the server security realm.
b) application-client.bat – it starts lightweight container for client applications that communicate with JBoss. More can be found in this link.
c) init.d – folder containing example run-scripts for running JBoss as a service on linux machine. Be careful! The script may need tweaking to run seamlessly on your system.
d) jboss-cli – I will describe this utility later. It is management utility allowing admins to change server configuration from command line
e) jconsole.bat – widely known tool to monitor working JVM
f) jdr.batJBoss Diagnostic Reporter. It will collect useful data from the server, resulting in ZIP file which can be used eg. by support from JBoss
g) run.bat – legacy launch script, not used
h) vault.bat – command line tool to secure sensitive data
i) wsconsume/wsprovide – are command line tools (and also Ant tasks) to generate webservice from WSDL (wsconsume) or from endpoint class (wsprovide)

Now we know our way around. We can finally start Wildfly in standalone mode and the end of run process should be logged similar to this:

21:00:18,761 INFO [org.jboss.ws.common.management] (MSC service thread 1-3) JBWS022052: Starting JBoss Web Services – Stack CXF Server 4.3.2.Final
21:00:19,045 INFO [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://127.0.0.1:9990/management
21:00:19,048 INFO [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990
21:00:19,050 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly 8.2.0.Final “Tweek” started in 16305ms – Started 184 of 234 services (82 services are lazy, passive or on-demand)

In order to check if everything is ok we can download sample applications for Wildfly from official GitHub page. The most basic is of course helloworld. Just go to the folder You cloned the code and issue the command (with server still running):

mvn clean package wildfly:deploy

In server’s log we should see something like this:

21:21:39,944 INFO [org.wildfly.extension.undertow] (MSC service thread 1-8) JBAS017534: Registered web context: /wildfly-helloworld
21:21:40,894 INFO [org.jboss.as.server] (management-handler-thread – 1) JBAS018559: Deployed “wildfly-helloworld.war” (runtime-name : “wildfly-helloworld.war”)

Right now the only thing left to se is working application. We can visit http://localhost:8080/wildfly-helloworld and see if everything is ok. There should be plain and simple Hello World message on the screen.

Server’s administration

Main idea behind Jboss lately is to avoid editing XML files in order to perform administrative tasks. It is good thing – while doing changes using prepared application it is possible to perform additional validation, which avoid errors. By default console application is accessible on port 9990, although if we visit it right now that is the view we are going to see:

NoUser

As mentioned we must create user to access the app. Remember the list of additional scripts in bin folder? There was script add-user.bat – we are going to use it right now. Process is simple – just add new Management User and follow the questions on the screen. When finished, You can log in http://localhost:9990/console and see something like this.

WildflyConsole

It means we have admin user and server is working properly. More about admin-related tasks can be found on Akquinet.

So how to deploy an app?

When we do not want to use Maven plugins deployment process is fairly simple.

  • GUI application – just visit Deployments tab in this app and point to existing file.
  • Auto deploy – the same way as it was done in previous versions. Just copy new file to standalone/deploy folder and it will be picked up by server automatically.
  • CLI deployment – quite obvious (example taken from the docs):
    // run jboss-cli.bat
    // type 'connect' to connect to running instance
    
    [standalone@localhost:9999 /] deploy ~/Desktop/test-application.war
    'test-application.war' deployed successfully.
     
    [standalone@localhost:9999 /] undeploy test-application.war
    Successfully undeployed test-application.war.
    

Where are my logs?

At the end I will describe problem I’ve faced while deploying my app to development server. The title is right – I could not find my log files. On my local machine slf4j and logback were used, creating two separate files with logs. One for SQL statements and one for everything else. When I deployed application to the Jboss it did not work.

Wildfly has modular architecture. Logging is performed by logging subsystem that can be configured in several ways (yep, console application is one of them). But before that subsystem kicks in, server logging during startup is done via logging.properties file, that resides in configuration directory. I saw that file and was sure that this is final config. Unfortunately it is not. As I’ve mentioned – it is used only before logging subsystem starts.

This subsystem has simple property – add-logging-api-dependencies, that when set to true will force server to provide logging libraries and dependencies. That makes my application’s logging config not working. To fix that I could change above setting, but it was impossible as it affects whole server. So there is another solution. I’ve added file jboss-deployment-structure.xml to my WEB-INF. It is one of deployment descriptors recognized by JBoss. The file looked like this:

<jboss-deployment-structure>
    <deployment>        
        <exclusions>
            <module name="org.slf4j" />
            <module name="org.slf4j.impl" />
            <module name="org.slf4j.api" />
            <module name="org.slf4j.jcl.over.slf4j" />
            <module name="org.apache.log4j" />
            <module name="ch.qos.logback.core" />
            <module name="ch.qos.logback.classic" />
        </exclusions>
    </deployment>
</jboss-deployment-structure>

It excludes modules with given name, but can be done better as described in this forum thread

<jboss-deployment-structure>  
  <deployment>  
     <!-- exclude-subsystem prevents a subsystems deployment unit processors running on a deployment -->  
     <!-- which gives basically the same effect as removing the subsystem, but it only affects single deployment -->  
     <exclude-subsystems>  
        <subsystem name="logging" />  
    </exclude-subsystems>  
</jboss-deployment-structure> 

After deployment everything started to work as expected.

Hacking as game

Recently I’ve been interested in several different areas of computer science, one of which is web/system security. I am not trying to join Anonymous or something ;), but You can never have enough knowledge. Due to that fact I’ve stumbled upon a nice page, with some kind of CTF-like games or tasks, which can greatly increase Your knowledge about linux, web and security. I have not ended all tasks but it can be really fun. Here is the page – http://overthewire.org/.

Shortcut for jRebel executor in Intellij Idea

I have recently started working again with Intellij Idea with jRebel. This tool-combo is one of the best things that ever happened to me, although I faced a little problem.

When running Tomcat instance from Intellij (with jRebel configured properly) You should use a little rocket icon on your toolbar.

WhichIcon

After clicking it Tomcat starts and there is console window at the bottom of the screen. But imagine the situation when this window is hidden – You toggled fullscreen mode or searched for something. The only way to show that window again was to use mouse and go to menu View->Tool Windows and the find JRebel Executor. I tried to assign shortcut for this (similar to simple Run action), but I could not find proper action on the shortcut list (menu File->Settings->Keymap). The solution is simple – Tomcat with JRebel must be TURNED ON to create this shortcut!! While running Intellij Idea will show additional item for JRebel executor in actions list! Just assign it shortcut You want and viola, it works.

Link

Z pewno艣ci膮 znacie ten b贸l, kiedy u偶ywa si臋 jednego z framework贸w czy j臋zyk贸w JVM, kt贸rych kolejne wersje wychodz膮 do艣膰 cz臋sto i dobrze by艂oby od czasu do czasu uaktualni膰 istniej膮ce instalacje. Zazwyczaj ko艅czymy z du偶膮 ilo艣ci膮 poinstalowanych wersji, w r贸偶nych miejscach i nie wiedz膮c do ko艅ca ile tego mamy i gdzie. Je偶eli nie jest to sytuacja Wam obca polecam zapoznanie si臋 z bardzo fajnym narz臋dziem o nazwie GVM, kt贸re jest napisane w czystym bash-u, a do sprawnego dzia艂ania potrzebuje tylko curl-a oraz unzip-a. Narz臋dzie to pozwala w bardzo wygodny spos贸b zarz膮dza膰 wszystkimi zainstalowanymi wersjami najr贸偶niejszych bibliotek – oto lista obecnie wspieranych:

  • Groovy
  • Grails
  • Griffon
  • Gradle
  • Groovyserv
  • Lazybones
  • vert.x
  • Crash
  • Glide
  • Gaiden
  • JBake
  • Springboot

Wi臋cej informacji oraz sposoby u偶ycia mo偶na znale藕膰 na oficjalnej stronie narz臋dzia.

Link

Ostatnio przegl膮daj膮c zasoby online na stronach Springa natkn膮艂em si臋 na ca艂kiem fajne narz臋dzie. Je艣li potrzebujecie wyprodukowa膰 gotowy projekt to wypr贸bujcie ten generator projekt贸w online. Do wyboru Maven oraz Gradle, z j臋zyk贸w Java lub Groovy i oczywi艣cie ca艂a rodzina produkt贸w ze stajni Springa. Polecam.

Parser log贸w w Groovy

Podczas debugowania wadliwego dzia艂ania redeliveringu w ActiveMQ ostateczn膮 metod膮 okaza艂o si臋 ‘echo dupa’ 馃槈 Jednak偶e przy pr贸bie jednoczesnego obserwowania dzia艂ania aplikacji przy 10 wiadomo艣ciach wpadaj膮cych do kolejki okaza艂o si臋, 偶e metoda kartki i papieru zabiera troch臋 za du偶o czasu. Zatem zaprz臋g艂em do pracy Grooviego i postanowi艂em na szybko napisa膰 ma艂y parserek plik贸w z logami.

G艂贸wne pomys艂y i kod podkrad艂em z tej strony. Jednak偶e ja do log贸w zapisywa艂em informacj臋 o tym, kt贸ra to pr贸ba ponownego dor臋czenia si臋 wykonuje, ilo艣膰 艂膮cznych, informacj臋 o w膮tku, kt贸ry to wykonuje oraz informacji z samej wiadomo艣ci w kolejce JMS. 聽To oczywi艣cie by艂o dopisywane do wiersza ze wskazaniem informacji o w膮tku i daty. Ca艂o艣膰 wygl膮da艂a mniej wi臋cej tak:

[#|2012-02-17T11:16:02.419+0100|INFO|sun-appserver9.1|javax.enterprise.system.stream.out|_ThreadID=80;_ThreadName=testowaKolejka-1;|CURRENT:4 MAX:4 id:identyfikator1-1-1-1|#]

I z tego narodzi艂 si臋 poni偶szy kod. By膰 mo偶e komu艣 si臋 przyda w przysz艂o艣ci.

/* Mozna uzyc podejscia, ktore odczytuje plik linia po linii. Jednakze
 istnieje szansa, ze 1 wpis do loga zajmie wiecej niz domyslna 1 linie.
 Dlatego tez uzywamy podejscia, ktore wyciagnie plik do 1 lancucha tekstowego
 nastepnie zas kolejne przyporzadkowania do wzorca wyrazen regularnych.

 !!!UWAGA!!! - rozwiazanie moze byc malo wydajne przy duzych plikach

  */

def logLineStart = /^\[\#\|\d{4}-\d{2}-\d{2}/   // Wpis w logu o wyjatku
def log = new File('C:\\log.log').text
def informationEntries = []
def presentationData = [:]

def splitter = log =~ """(?xms)
    (    ${logLineStart}   .*?)
    (?=  ${logLineStart} | \\Z)
"""

splitter.each { matched, entry ->

    // Replace jest po to by otrzymac jeden lancuch tekstowy w przypadku dopasowan ze znakiem
    // nowej linii. Wowczas dane nie bylyby poprawne.
    if (entry =~ /CURRENT:/) {
         informationEntries.add( entry.replaceAll("[\r\n]","") )
    }

}

def redeliveryAttemptData = []

informationEntries.each {
    // Wpisy na liscie wygladaja mniej wiecej tak
    // [#|2012-02-17T15:49:50.525+0100|INFO|sun-appserver9.1|javax.enterprise.system.stream.out|_ThreadID=134;_ThreadName=testowaKolejka-1;|CURRENT:4 MAX:4 id:identyfikator1-1-1-1|#]

    // Zatem po prostu rozbijamy ten string i wyciagamy dane z listy
    redeliveryAttemptData = it.tokenize('|')

    String currentEntryData = redeliveryAttemptData.get(1)
    String currentEntryThread = redeliveryAttemptData.get(5)
    String currentEntryInfo = redeliveryAttemptData.get(6)

    // Wpierw potrzebna nam data i godzina z dokladnoscia do sekund
    def dataRegexp = /\d{2}:\d{2}:\d{2}\.\d{3}/
    def currentMinutesSec =  currentEntryData.find(dataRegexp)

    // Informacja o numerze watku, ktory procesowal wiadomosc
    def threadRegexp = /=jmsContainerEmailIn-\d{1,}/
    def currentThreadInfo =  currentEntryThread.find(threadRegexp).tokenize('-').get(1)

    // Logowane przeze mnie informacje o wiadomosci i metadane redeliveringu
    def listWithCurrentInfo = currentEntryInfo.tokenize(' ')
    def currentRound = listWithCurrentInfo.get(0).tokenize(':').get(1)
    def currentId = listWithCurrentInfo.get(2).tokenize(':').get(1)

    if( !presentationData[ currentId ] ) {
        presentationData[ currentId ] = [:]
    }

    presentationData[ currentId ][ 'id' ] = currentId
    presentationData[ currentId ][ currentRound ] = currentMinutesSec + '( ' + currentThreadInfo + ' )'

}

// Drukujemy na konsole w formie CSV. Mozna inaczej - stad
// zreszta zapisywanie danych do mapy
presentationData.each { key, value ->

    StringBuffer sb = new StringBuffer(64)

    sb.append( value.get('id')).append(',')

    for ( i in ['0','1','2','3','4'] ) {
        sb.append( value.get( i ) ).append(',')
    }

    println sb

}

Narz臋dzia JDK

W przypadku聽JDK聽najcz臋艣ciej wiemy, 偶e trzeba go zainstalowa膰 by m贸c co艣 zaprogramowa膰. Cz臋sto na samej instalacji nasza przygoda z聽JDK聽si臋 ko艅czy – reszt臋 bior膮 na siebie IDE czy 艣cie偶ka systemowa do kompilatora i tyle. Tymczasem warto zapozna膰 si臋 z聽JDK聽troch臋 bli偶ej – dostarcza on bowiem szeregu ca艂kiem przyjemnych narz臋dzi. W swoim wywodzie pomin臋 najbardziej oczywiste – java oraz javac. Chyba ka偶dy wie, 偶e u偶ywa kompilatora oraz uruchamia oddzielne instancje JVM 馃槈

Lista z ca艂膮 pewno艣ci膮 nie jest kompletna, nie ma r贸wnie偶 s艂u偶y膰 za tutorial dotycz膮cy ich u偶ycia. Ma tylko pokaza膰 istnienie pewnych programik贸w, kt贸re mog膮 nam si臋 przyda膰. Wiekszo艣膰 z ni偶ej wymienionych posiada dodatkowe opcje i parametry, kt贸rymi mo偶emy sterowa膰 uruchomienie oraz dzia艂anie program贸w. Ca艂o艣膰 testowa艂em na JDK od Sun/Oracle w wersjach 1.6 oraz 1.7

  • JPS 聽– jest to narz臋dzie pozwalaj膮ce wylistowa膰 uruchomione (domy艣lnie) na lokalnym komputerze maszyny wirtualne. W charakterze parametru mo偶na poda膰 dowolny adres komputera (zdalnego), oczywi艣cie pod warunkiem, 偶e mamy do niego dost臋p. R贸wnie偶 nale偶y zwr贸ci膰 uwag臋 na opis w dokumentacji:

    The jps command uses the java launcher to find the class name and arguments passed to the main method. If the target JVM is started with a custom launcher, the class name (or JAR file name) and the arguments to the main method will not be available. In this case, the jps command will output the string Unknown for the class name or JAR file name and for the arguments to the main method.

    The list of JVMs produced by the jps command may be limited by the permissions granted to the principal running the command. The command will only list the JVMs for which the principle has access rights as determined by operating system specific access control mechanisms.

    Dodatkowo dokumentacja m贸wi jasno, i偶 JPS nie jest ju偶 wspierane i mo偶e znikn膮膰 w kolejnych wersjach Javy. U mnie w JDK 1.7.0 wci膮偶 jest dost臋pne 馃槈

  • Appletviewer – zgodnie z nazw膮 s艂u偶y do uruchamiania applet贸w bez konieczno艣ci osadzania ich na loklanej stronie WWW (czy te偶 gdzie艣 indziej). Dla przyk艂adu – mamy gr臋 w Javie w formie apletu, ale nie chcemy uruchamia膰 ca艂ej otaczaj膮cej aplet strony (z mas膮 reklam). Podajemy adres strony zawieraj膮cej element z apletem i do przodu. Niestety nale偶y si臋 r贸wnie偶 liczy膰 z tym, i偶 mog膮 wyst膮pi膰 problemy z uruchomieniem – przekazywane parametry, sprawdzanie poprawno艣ci, cookie – ewentualnych przyczyn braku poprawnego uruchomienia jest wiele. Jednak偶e by zobaczy膰 cho膰 w praktyce jak to wygl膮da wystarczy uruchomi膰 z konsoli to narz臋dzie przekazuj膮c jako pierwszy argument adres: http://www.roseindia.net/tutorialfiles/java/applet-oline-example.html . Hello World!
  • JSTAT i JSTATD – to bardzo pot臋偶ne narz臋dzia, kt贸re umo偶liwiaj膮 monitoring parametr贸w JVM. JStad uruchamia lokalny rejestr RMI, co umo偶liwia wystawienie informacji o JVM na zewn膮trz (np. w艂膮czenie 艂adnego monitoringu w formie aplikacji webowej uruchomionej na innym serwerze). Na szybko za艣 powiem wi臋cej o Jstat, kt贸re to narz臋dzie pozwala na do艣膰 dok艂adne monitorowanie parametr贸w JVM. G艂贸wnie rzecz w zaj臋to艣ci pami臋ci oraz zdarzeniach Garbage Collectora. Jest to naprawd臋 bardzo istotne w przypadku wyciek贸w pami臋ci, monitoringu zmian oraz badaniach efektywno艣ci. Zwracane warto艣ci mog膮 by膰 r贸偶nie formatowane i dobrze jest zapozna膰 si臋 z nimi w dokumentacji .
  • Javap – narz臋dzie u偶yteczne do艣膰 w w膮skim zakresie. Jego wywo艂anie z argumentem w formie klasy spowoduje zwr贸cenie danych o pakiecie oraz publicznych i chronionych polach/metodach. Oczywi艣cie wynik programu mo偶emy regulowa膰 za pomoc膮 du偶ej ilo艣ci opcji. Przydatne kiedy debugujemy kod na zapomnianym serwerze z Jav膮 1.3 bez dost臋pu do API w innej postaci (man, internet, IDE) 馃槈
  • JDB – debugger dla Javy. Je艣li my艣l o pr贸bach zabawy z tym narz臋dziem bez IDE przyprawia Ci臋 o dr偶enie r膮k to wiedz, 偶e nie jeste艣 jedynym.
  • JMap i JHat – narz臋dzia do tworzenia zrzut贸w sterty oraz do ich analizy. Parametrem do analizy przez program JHat mo偶e by膰 efekt dzia艂ania JMap. Program JHat po przeanalizowaniu pliku uruchamia serwer WWW i udost臋pnia dane na temat zrzutu.
  • JConsole i JVisualVM – 艂adne narz臋dzia graficzne do zarz膮dzania i statystyki JVM (zar贸wno lokalnych jak i zdalnych). S膮 to nak艂adki wykorzystujace niekt贸re wspomniane powy偶ej narz臋dzia. D艂ugo by pisa膰 – zach臋cam do zapoznania si臋 z nimi.

Pozosta艂e narz臋dzia s膮 w fazie eksperymentalnej (np. jrunscript) b膮d藕 te偶 do艣膰 cz臋sto u偶ywane, ale przez inne biblioteki i narz臋dzia (wsgen, javadoc, xjc, jar). Wielu z powy偶szych narz臋dzi mo偶emy nigdy nie potrzebowa膰. Warto jednak zajrze膰 do folderu BIN, tak tylko z wrodzonej ciekawo艣ci 馃槈