Pages

Friday, January 29, 2016

Fun with Oracle DB: ORA-00907

Following SQL select statement leads to an "ORA-00907: missing right parenthesis" warning message:
select * from A a
where a.id in (select b.id from B b order by b.id)
Hm. I don't see anything missing... Ok, let's remove the order clause, as it is not really needed:
select * from A a
where a.id in (select b.id from B b)
And, voilĂ ! No ORA-00907. And it seems that I am not the only one having these troubles, see the blog entry by oraclequirks.

Friday, January 15, 2016

Gradle: From zero to war

Kickstart for creating Java web project with the gradle buildtool.

The well known gradle init task is an easy way to create a Java project:

[520]% gradle init --type java-library

However, there is no support for initializing a web application. Alternatively, you may use the cool gradle-templates of townsfolk: https://github.com/townsfolk/gradle-templates.

How this may be done, is described below.

Step 0: Create master gradle script

Create a master build.gradle script. This may be done anywhere. However, I use the project parent directory where all my projects are found:

buildscript {
    repositories {
        maven {
            url 'http://dl.bintray.com/cjstehno/public'
        }
    }
    dependencies {
        classpath 'gradle-templates:gradle-templates:1.4.1'
    }
}
apply plugin:'templates'

List the tasks:

> gradle tasks
[...]
Template tasks
--------------
createGradlePlugin - Creates a new Gradle Plugin project in a new directory named after your project.
createGroovyClass - Creates a new Groovy class in the current project.
createGroovyProject - Creates a new Gradle Groovy project in a new directory named after your project.
createJavaClass - Creates a new Java class in the current project.
createJavaProject - Creates a new Gradle Java project in a new directory named after your project.
createScalaClass - Creates a new Scala class in the current project.
createScalaObject - Creates a new Scala object in the current project.
createScalaProject - Creates a new Gradle Scala project in a new directory named after your project.
createWebappProject - Creates a new Gradle Webapp project in a new directory named after your project.
exportAllTemplates - Exports all the default template files into the current directory.
exportGroovyTemplates - Exports the default groovy template files into the current directory.
exportJavaTemplates - Exports the default java template files into the current directory.
exportPluginTemplates - Exports the default plugin template files into the current directory.
exportScalaTemplates - Exports the default scala template files into the current directory.
exportWebappTemplates - Exports the default webapp template files into the current directory.
initGradlePlugin - Initializes a new Gradle Plugin project in the current directory.
initGroovyProject - Initializes a new Gradle Groovy project in the current directory.
initJavaProject - Initializes a new Gradle Java project in the current directory.
initScalaProject - Initializes a new Gradle Scala project in the current directory.
initWebappProject - Initializes a new Gradle Webapp project in the current directory.
[...]

As you can see, there are many different templates you may use. For our purpose, the createWebappProject task seems to be interesting.

Step 1: Create the web project

Use the createWebappProject task for creating a new fresh web project. Invoke the task and answer some questions:

> gradle createWebappProject
:createWebappProject

templates> Project Name:  (WAITING FOR INPUT BELOW)
> Building 0% > :createWebappProjecttestweb

templates> Project Parent Directory: [/Development/java/projects/projects-test]  (WAITING FOR INPUT BELOW)
> Building 0% > :createWebappProject

templates> Use Jetty Plugin? (Y|n) [n]  (WAITING FOR INPUT BELOW)
> Building 0% > :createWebappProjectY

templates> Group: [testweb]  (WAITING FOR INPUT BELOW)
> Building 0% > :createWebappProject

templates> Version: [0.1]  (WAITING FOR INPUT BELOW)
> Building 0% > :createWebappProject

BUILD SUCCESSFUL

Total time: 25.877 secs

Check the generated files and directories:

> cd testweb/
> find .
.
./build.gradle
./gradle.properties
./LICENSE.txt
./src
./src/main
./src/main/java
./src/main/resources
./src/main/webapp
./src/main/webapp/WEB-INF
./src/main/webapp/WEB-INF/web.xml
./src/test
./src/test/java
./src/test/resources

List the tasks:

> gradle tasks
Build tasks
-----------
[...]
war - Generates a war archive with all the compiled classes, the web-app content and the libraries.
[...]

Web application tasks
---------------------
jettyRun - Uses your files as and where they are and deploys them to Jetty.
jettyRunWar - Assembles the webapp into a war and deploys it to Jetty.
jettyStop - Stops Jetty.
[...]

Step 2: Create your first page and run it

Create the landing page:

> echo "Hello" > src/main/webapp/index.html

And finally, run the web application in Jetty:

> gradle jettyRun
Starting a new Gradle Daemon for this build (subsequent builds will be faster).
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
> Building 75% > :jettyRun > Running at http://localhost:8080/testweb

Open your browser http://localhost:8080/testweb/ and you should see the welcome message.

Friday, June 19, 2015

How to set up Eclipse template for inserting SLF4J Logger

Adding private static final Logger logger = LoggerFactory.getLogger(XXX.class); by hand to your Java classes is tiring.

Use Eclipse template. For SLF4J this looks as follows:
private static final Logger LOG 
  = LoggerFactory.getLogger(${enclosing_type}.class);
  ${:import(org.slf4j.Logger,org.slf4j.LoggerFactory)}
Note, that there are two import statements, one for the Logger and another for the LoggerFactory class.

The single steps needed to configure this template in the IDE, is explained in an older post here.

Friday, June 13, 2014

Init GIT repository on my Google Drive

Some GIT basics mainly for me to remember. I use Google Drive as a poor man solution to share some Java test projects between my work place and my home. And that's how I have done it. First, init the (local) repository at Google Drive. On MacOS, the directory can be found at ~/Google\ Drive/:
cd ~/Google\ Drive/
mkdir projects
cd projects
mkdir my_project.git
cd my_project.git
git init --bare
In the test project workspace, a project is added to the repository as follows:
cd my_project
git init
git add *
git commit -m "My initial commit message"
git remote add origin ~/Google\ Drive/projects/my_project.git
git push -u origin master
Now I can clone the project:
git clone ~/Google\ Drive/projects/my_project.git
cd my_project

Friday, June 6, 2014

Running Node.js in Docker

0. Inform

This is basically a copy of the Hello World example found here and here with some additional comments.

1. Make the VM running

boot2docker up

2. Build the Docker image

Create your Node.js application index.js file:
var express = require('express');
var DEFAULT_PORT = 8080;
var PORT = process.env.PORT || DEFAULT_PORT;
var app = express();
app.get('/', function (req, res) {
  res.send('Hello World\n');
});
app.listen(PORT)
console.log('Running on http://localhost:' + PORT);
Create the Docker package.json file:
{
  "name": "docker-centos-hello-world",
  "private": true,
  "version": "0.0.1",
  "description": "Node.js Hello World app on CentOS using docker",
  "author": "Daniel Gasienica",
  "dependencies": {
    "express": "3.2.4"
  }
}
Create the Dockerfile:
FROM centos:6.4
RUN rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
RUN yum install -y npm
ADD . /src
RUN cd /src; npm install
EXPOSE 8080
CMD ["node", "/src/index.js"]
The layout of your directory should be as follows:
> ls
Dockerfile   index.js   package.json
Building the image:
docker build -t peter/centos-node-hello .
Verify if the image exists:
docker images
This should print:
REPOSITORY                TAG                   IMAGE ID            CREATED             VIRTUAL SIZE
peter/centos-node-hello   latest                6c55823e6868        4 hours ago         672.2 MB

3. Running

docker run -p 49160:8080 -d peter/centos-node-hello
The option -p exposes the port 8080 to 49160. This is essential. Without that, the server is not visible to a client.

Verify, if the process is running:
docker ps
You should see:
CONTAINER ID        IMAGE                            COMMAND              CREATED             STATUS              PORTS                     NAMES
578bd01b0407        peter/centos-node-hello:latest   node /src/index.js   4 hours ago         Up 2 hours          0.0.0.0:49160->8080/tcp   jovial_feynman  
Inspect the image:
docker inspect 578bd01b0407
You should see a JSON output showing all relevant information:
...
"PortBindings": {
    "8080/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "49160"
        }
    ]
}
...
If the -p was not given when starting the process, HostPort would have been null and the application would not have been visible to clients. Test it:
curl localhost:49160
Now you should see:
Hello World.
Stop and start the process again:
docker stop 578bd01b0407
docker ps doesn't show the process any more. docker ps -a lists the process as Exited:
> docker ps -a
CONTAINER ID        IMAGE                            COMMAND              CREATED             STATUS                       PORTS               NAMES
578bd01b0407        peter/centos-node-hello:latest   node /src/index.js   12 minutes ago      Exited (143) 9 seconds ago                       jovial_feynman     
So, start it again:
docker start 578bd01b0407
Test if the process is running:
> docker -ps
CONTAINER ID        IMAGE                            COMMAND              CREATED             STATUS              PORTS                     NAMES
578bd01b0407        peter/centos-node-hello:latest   node /src/index.js   14 minutes ago      Up 2 seconds        0.0.0.0:49160->8080/tcp   jovial_feynman 
Check the logs:
> docker logs 578bd01b0407
Running on http://localhost:8080
Running on http://localhost:8080

Running Docker on MacOS

0. Inform

Almost all information about installing docker on MacOS can be found here:

    http://docs.docker.io/installation/mac/

1. Install VirtualBox

Download VirtualBox from here:

    https://www.virtualbox.org/wiki/Downloads

Double-click the *.dmg file and install the application following the install dialog.

2. Install boot2docker

boot2docker is used to manage the docker VMs. The installer for MacOS can be found here:

    https://github.com/boot2docker/osx-installer/releases

Double-click the Docker.dmg file and install the application following the install dialog.

3. Install Docker client

Installation routine:
> mkdir tmp
> cd tmp
> curl -f -o ./ld.tgz https://get.docker.io/builds/Darwin/x86_64/docker-latest.tgz
> gunzip ld.tgz 
> tar xvf ld.tar 
> sudo cp usr/local/bin/docker /usr/local/bin
Specify the docker deamon Host for the client:
export DOCKER_HOST=tcp://127.0.0.1:4243

4. Initialize boot2docker VM and run deamon

Initialize the VM:
> boot2docker init
2014/06/06 09:51:37 Downloading boot2docker ISO image...
2014/06/06 09:51:38 Latest release is v0.9.1
2014/06/06 09:52:01 Success: downloaded https://github.com/boot2docker/boot2docker/releases/download/v0.9.1/boot2docker.iso
    to /Users/peterkeller/.boot2docker/boot2docker.iso
Generating public/private rsa key pair.
...
2014/06/06 09:53:03 Creating VM boot2docker-vm...
2014/06/06 09:53:04 Apply interim patch to VM boot2docker-vm (https://www.virtualbox.org/ticket/12748)
2014/06/06 09:53:04 Setting NIC #1 to use NAT network...
2014/06/06 09:53:04 Port forwarding [ssh] tcp://127.0.0.1:2022 --> :22
2014/06/06 09:53:04 Port forwarding [docker] tcp://127.0.0.1:4243 --> :4243
2014/06/06 09:53:04 Setting NIC #2 to use host-only network "vboxnet0"...
2014/06/06 09:53:04 Setting VM storage...
2014/06/06 09:53:10 Done. Type `boot2docker up` to start the VM.
Running the deamon:
> boot2docker up
2014/06/06 09:55:23 Waiting for SSH server to start...
2014/06/06 09:55:47 Started.
2014/06/06 09:55:47 To connect the Docker client to the Docker daemon, please set:
2014/06/06 09:55:47     export DOCKER_HOST=tcp://localhost:4243
Test:
> docker version
Client version: 0.11.1
Client API version: 1.11
Go version (client): go1.2.1
Git commit (client): fb99f99
Server version: 0.11.1
Server API version: 1.11
Git commit (server): fb99f99
Go version (server): go1.2.1
Setup forward network ports. According to the documentation, the boot2docker VM must be powered off for this to work:
> boot2docker stop
Run following script (this takes a while):
for i in {49000..49900}; do
 VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port$i,tcp,,$i,,$i";
 VBoxManage modifyvm "boot2docker-vm" --natpf1 "udp-port$i,udp,,$i,,$i";
done
Starting docker VM again and login using ssh:
> boot2docker up
> boot2docker ssh
Then you should see:

                        ##        .
                  ## ## ##       ==
               ## ## ## ##      ===
           /""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
           \______ o          __/
             \    \        __/
              \____\______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|

Friday, May 9, 2014

JBoss Wildfly with Apache Camel: first unsuccessful test

Today, I tried to setup the Wildfly Camel integration. Unfortunately, I was not successful. Please see what I have tried.

For my tests I used Wildfly 8.0.0.Final and the Wildfly Camel integration installer 1.0.0.Alpha1.

Step 1: Download

Download the Wildfly Camel installer from http://sourceforge.net/projects/jboss/files/WildFly-Camel/1.0.0.Alpha1/

This will download the installer file wildfly-camel-installer-1.0.0.Alpha1.jar

Step 2: Install

> cd wildfly-8.0.0.Final/
> java -jar wildfly-camel-install-1.0.0.Alpha1.jar

This will install among others all necessary jars in the modules directory and the standalone camel configuration file standalone/configuration/standalone-camel.xml.

Step 3: Running

>  cd bin
> ./standalone.sh -c standalone-camel.xml

 This will produce following error:

[521]% ./standalone.sh -c standalone-camel.xml
=========================================================================

  JBoss Bootstrap Environment

  JBOSS_HOME: /Developer/Workspace/Java/containers/wildfly-8.0.0.Final

  JAVA: /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/bin/java

  JAVA_OPTS:  -server -XX:+UseCompressedOops -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true

=========================================================================

18:24:00,635 INFO  [org.jboss.modules] (main) JBoss Modules version 1.3.0.Final
18:24:02,615 INFO  [org.jboss.msc] (main) JBoss MSC version 1.2.0.Final
18:24:02,950 INFO  [org.jboss.as] (MSC service thread 1-7) JBAS015899: WildFly 8.0.0.Final "WildFly" starting
18:24:05,915 ERROR [org.jboss.as.server] (Controller Boot Thread) JBAS015956: Caught exception during boot: org.jboss.as.controller.persistence.ConfigurationPersistenceException: JBAS014676: Failed to parse configuration
    at org.jboss.as.controller.persistence.XmlConfigurationPersister.load(XmlConfigurationPersister.java:112) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.server.ServerService.boot(ServerService.java:331) [wildfly-server-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.controller.AbstractControllerService$1.run(AbstractControllerService.java:256) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_40]
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[107,21]
Message: JBAS014788: Unexpected attribute 'host' encountered
    at org.jboss.as.controller.parsing.ParseUtils.unexpectedAttribute(ParseUtils.java:104) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.messaging.MessagingSubsystemParser.processConnectors(MessagingSubsystemParser.java:1102)
    at org.jboss.as.messaging.MessagingSubsystemParser.processHornetQServer(MessagingSubsystemParser.java:227)
    at org.jboss.as.messaging.Messaging13SubsystemParser.processHornetQServers(Messaging13SubsystemParser.java:212)
    at org.jboss.as.messaging.MessagingSubsystemParser.readElement(MessagingSubsystemParser.java:134)
    at org.jboss.as.messaging.MessagingSubsystemParser.readElement(MessagingSubsystemParser.java:93)
    at org.jboss.staxmapper.XMLMapperImpl.processNested(XMLMapperImpl.java:110) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.staxmapper.XMLExtendedStreamReaderImpl.handleAny(XMLExtendedStreamReaderImpl.java:69) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.as.server.parsing.StandaloneXml.parseServerProfile(StandaloneXml.java:1131) [wildfly-server-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.server.parsing.StandaloneXml.readServerElement_1_4(StandaloneXml.java:458) [wildfly-server-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.server.parsing.StandaloneXml.readElement(StandaloneXml.java:145) [wildfly-server-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.server.parsing.StandaloneXml.readElement(StandaloneXml.java:107) [wildfly-server-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.staxmapper.XMLMapperImpl.processNested(XMLMapperImpl.java:110) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.staxmapper.XMLMapperImpl.parseDocument(XMLMapperImpl.java:69) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.as.controller.persistence.XmlConfigurationPersister.load(XmlConfigurationPersister.java:104) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    ... 3 more

18:24:05,920 FATAL [org.jboss.as.server] (Controller Boot Thread) JBAS015957: Server boot has failed in an unrecoverable manner; exiting. See previous messages for details.
18:24:05,969 INFO  [org.jboss.as] (MSC service thread 1-7) JBAS015950: WildFly 8.0.0.Final "WildFly" stopped in 4ms


That's too bad.  Obviously, the XML configuration file standalone-camel.xml created by the installer meets not the schema expected by the final Wildfly 8.0.0 version. It turns out that the Netty connector definition is mal-configured.

Step 4: Extending standalone.xml

Try to fix the configuration starting with the default standalone.xml file.

Adding Camel extension:

<extension module="org.wildfly.camel" />

Adding subsystem with simple Camel context:

<subsystem xmlns="urn:jboss:domain:camel:1.0">
    <camelContext id="system-context-1">
         &lt;route&gt;
             &lt;from uri="direct:start"/&gt;
             &lt;transform&gt;
                 &lt;simple&gt;Hello #{body}&lt;/simple&gt;
             &lt;/transform&gt;
         &lt;/route&gt;      
    </camelContext>
 </subsystem>


Starting Wildfly as described in Step 3 leads to following error message in the console:

19:27:30,306 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 28) JBAS014612: Operation ("add") failed - address: ([("subsystem" => "camel")]): java.lang.NoSuchMethodError: org.jboss.as.naming.service.BinderService.getManagedObjectInjector()Lorg/jboss/msc/inject/Injector;
    at org.wildfly.camel.service.CamelContextFactoryBindingService.addService(CamelContextFactoryBindingService.java:66)
    at org.wildfly.camel.parser.CamelSubsystemAdd$1.execute(CamelSubsystemAdd.java:91)
    at org.jboss.as.controller.AbstractOperationContext.executeStep(AbstractOperationContext.java:591) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.controller.AbstractOperationContext.doCompleteStep(AbstractOperationContext.java:469) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.controller.AbstractOperationContext.completeStepInternal(AbstractOperationContext.java:273) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.controller.AbstractOperationContext.executeOperation(AbstractOperationContext.java:268) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.controller.ParallelBootOperationStepHandler$ParallelBootTask.run(ParallelBootOperationStepHandler.java:343) [wildfly-controller-8.0.0.Final.jar:8.0.0.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_40]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_40]
    at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_40]
    at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.1.Final.jar:2.1.1.Final]


Step 5: Giving up...

The Wildfly Camel integration sounds interesting. However, it seems not really ready for use. To be continued...


Sunday, May 4, 2014

Using Hawtio to monitor Apache Camel route started as Java standalone process

Step 1: Gathering info

http://hawt.io/getstarted/index.html

Step 2: Download Jolokia Java Agent

Download Jolokia JARs from:

http://jolokia.org/dist/1.2.1/jolokia-1.2.1-bin.zip

Unzip the file.

Step 3: Add VM arguments to for enabling Jolokia Java Agent

Add following VM arguments when starting your Java standalone client:

-javaagent:/path/to/-javaagent:/Developer/Workspace/Java/libs/jolokia-1.2.1/agents/jolokia-jvm.jar


Step 4: Start the Camel route

You should see something similar in your console

I> No access restrictor found, access to all MBean is allowed
Jolokia: Agent started with URL http://127.0.0.1:8778/jolokia/


Step 5: Download and install Chrom Client

Download extension:

http://central.maven.org/maven2/io/hawt/hawtio-crx/1.3.1/hawtio-crx-1.3.1.crx

Start Chrom and open extension path at chrome://extensions/

Drop the downloaded CRX file onto the page

Open the app page, select Hawtio app and enter the URL that was shown on Step 4. In my case this was port 8778 and path jolokia.

You should see the Hawtio page with your Camel route:



I especially like the Diagram tab showing the route layout:


Friday, May 2, 2014

JBoss Wildfly with Apache Camel

Wildfly Camel Integration

This sounds interesting: Apache Camel integration with the WildFly Application Server:
There are two ways to deploy a Camel Context to WildFly
  1. As a single XMl file with a predefined -camel-context.xml file suffix
  2. As part of another WildFly supported deployment as META-INF/jboss-camel-context.xml file 

JBoss Modules

Alternatively, see http://sourcevirtues.wordpress.com/2013/11/25/add-apache-camel-and-spring-as-jboss-module-in-wildfly/ how Camel dependencies can be added to JBoss Wildfly using JBoss modules.

JBoss Wildfly in 5 minutes (or a little bit more, but not much)

Step 1: Gathering information

Access:

http://www.wildfly.org/

Step 2: Download the server

Download Wildfly v8.0.0:

http://download.jboss.org/wildfly/8.0.0.Final/wildfly-8.0.0.Final.zip

Step 3: Install the server

> unzip wildfly-8.0.0.Final.zip

Step 4: Start the server

> cd wildfly-8.0.0.Final
> cd bin
> ./standalone.sh

On my not so fast iMac, the first time the server was started it took about 20 seconds, the second time only about 4 seconds:

11:36:10,083 INFO  [org.jboss.ws.common.management] (MSC service thread 1-4) JBWS022052: Starting JBoss Web Services - Stack CXF Server 4.2.3.Final
11:36:10,153 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://127.0.0.1:9990/management
11:36:10,154 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990
11:36:10,154 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly 8.0.0.Final "WildFly" started in 4221ms - Started 183 of 232 services (80 services are lazy, passive or on-demand)


Check if the server is started on http://localhost:8080. You should see the Wildfly welcome page.

Step 5: Access Administration console

http://localhost:9990

This will not work... It states:
To add a new user execute the add-user.sh script within the bin folder of your WildFly installation and enter the requested information.
 Try that and answer the questions:

> ./add-user.sh

I added an admin user. Access http://localhost:9990 again, and voilĂ , the admin cosole is shown.

Step 6: Deploy the first application

Clone from GitHub

> git clone https://github.com/wildfly/quickstart.git

Build and deploy the project:

> cd quickstart/
> mvn wildfly:deploy

You should see the following log messages:

11:46:40,620 INFO  [org.jboss.as.repository] (management-handler-thread - 1) JBAS014900: Content added at location /Developer/Workspace/Java/containers/wildfly-8.0.0.Final/standalone/data/content/0b/37af36408419a89a9c1f015ea3570c87ced389/content
11:46:40,707 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-1) JBAS015876: Starting deployment of "wildfly-helloworld.war" (runtime-name: "wildfly-helloworld.war")
11:46:42,141 INFO  [org.jboss.weld.deployer] (MSC service thread 1-7) JBAS016002: Processing weld deployment wildfly-helloworld.war
11:46:42,468 INFO  [org.hibernate.validator.internal.util.Version] (MSC service thread 1-7) HV000001: Hibernate Validator 5.0.3.Final
11:46:42,915 INFO  [org.jboss.weld.deployer] (MSC service thread 1-4) JBAS016005: Starting Services for CDI deployment: wildfly-helloworld.war
11:46:43,031 INFO  [org.jboss.weld.Version] (MSC service thread 1-4) WELD-000900: 2.1.2 (Final)
11:46:43,207 INFO  [org.jboss.weld.deployer] (MSC service thread 1-5) JBAS016008: Starting weld service for deployment wildfly-helloworld.war
11:46:45,711 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-1) JBAS017534: Registered web context: /wildfly-helloworld
11:46:45,860 INFO  [org.jboss.as.server] (management-handler-thread - 1) JBAS018559: Deployed "wildfly-helloworld.war" (runtime-name : "wildfly-helloworld.war")


Access the application:

http://localhost:8080/wildfly-helloworld/HelloWorld

You should see the "Hello World!" message.



Wednesday, April 9, 2014

Exclude external JavaScript libraries from beeing validated in Eclipse 4

Due to an Eclipse Bug, JavaScript errors of external JavaScript libraries are marked as erroronous showing the red failure marker even if JavaScript errors are excluded from the contents Markers view, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=349020

Workaround as spooted in the Eclipse bug history:
I have found that I can leave the JavaScript Validator enable and ignore 
specific files by adding a suitable exclusion pattern e.g. **/jquery*.js to 
the JavaScript/Include Path/Source/Excluded group 
(Project->Properties->JavaScript->Include Path->Source).

Friday, December 20, 2013

Importing SSL Certificates to a Keystore with Java Keytool

Java Keytool is a key and certificate tool for managing cryptographic keys, X.509 certificate chains, and trusted certificates.

Keytool Functions

  • Administration of public/private key pairs and associated certificates.
  • Administration of secret keys used in symmetric encryption/decryption (e.g. DES)
  • Storing keys and certificates in a keystore
In this blog I focus on the last aspect.

SSL Basics

 

File types

We distinguish between certificates and keystores:
  • Certificate: A digitally signed statement from one entity (person, company, etc.), saying that the public key (and some other information) of some other entity has a particular value. When data is digitally signed, the signature can be verified to check the data integrity and authenticity. Integrity means that the data has not been modified or tampered with, and authenticity means the data indeed comes from whoever claims to have created and signed it.
  • Keystore: Archive file (database) for storing many cryptography objects such as certificates as a single file.

Certificate encodings and extensions

  • .DER: Binary DER encoded certificates. Not routinely used by anything in common usage.
  • .PEM: ASCII (Base64) encoded DER certificates used for different types of X.509v3 files which contain data surrounded with -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----. PEM stands for Privacy-enhanced Electronic Mail.
  • .CRT: Used for certificates in DER or PEM format. Most common in *nix systems.
  • .CER: Alternate extension of .CRT. Microsoft convention.

Keystore formats and extensions

  • .JKS: Keystore in Java format, e.g. $JAVA_HOME/jre/lib/security/cacerts
  • .P12, .PKCS12, .PFX: PKCS12 certificate keystore file format. It is commonly used to bundle a private key with its X.509 certificate or to bundle all the members of a chain of trust.

Keytool Commands for Storing Keys and Certificates in a Keystore


Listing all imported certificates

keytool -list -keystore keystore.jks -storepass ***

Importing a single certificate to a keystore

keytool -importcert \
    -file mycert.pem \
    -destkeystore keystore.jks \
    -deststoretype jks \
    -deststorepass ***
    -alias myalias

Importing a PKCS12 keystore to a JKS keystore

This time we import not only a simple certificate but a whole keystore:
keytool -importkeystore \
    -srckeystore cert-and-key.p12 \
    -srcstoretype pkcs12 \
    -srcstorepass *** \
    -destkeystore keystore.jks \
    -deststoretype jks \
    -deststorepass *** \
If the destination keystore does not already exists it will be built. So the importing process becomes a format change process. If you do not enter the source or destination store passwords, you will be prompted for it. You may skip the type information if you are lazy and trust the keytool that it will recognize the correct type for you.

Importing a JKS keystore to a PKCS12 keystore

The same command as above but vice versa:
keytool -importkeystore \
    -srckeystore keystore.jks \
    -srcstoretype jks \
    -srcstorepass *** \
    -destkeystore cert-and-key.p12 \
    -deststoretype pkcs12 \
    -deststorepass *** \

Further Sources

Saturday, November 2, 2013

How to check if your iPhone is unlocked or not?

  1. Find the IMEI (International Mobile Equipment Identiy) number of your iPhone (Settings -> General -> Info section)
  2. Visit http://iphoneimei.info/ and enter your IMEI
  3. See the result


 Helpful (and a little bit scary...)

Sunday, June 23, 2013

FUSE ESB / Apache ServiceMix Basic Authentication

Find below a guide to setup up Basic Authentication for a Restful service running in a JBoss FUSE ESB 6.0 / Apache ServiceMix OSGI runtime. The service itself is not special. The notable configuration is found in blueprint.xml and in pom.xml.

Important note: this setup only works for JBoss FUSE ESB 6.0 or newer but not for FUSE ESB 7.1.0 or older!

The Restful service implementation CustomerService.java:
package ch.keller.servicemix.restws.server;

import java.util.Date;

import javax.annotation.Resource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;

import org.apache.cxf.jaxrs.ext.MessageContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Path("/customers")
public class CustomerService {
 
 private static final Logger LOG = LoggerFactory.getLogger(CustomerService.class);

 @Resource
 private MessageContext jaxrsContext;
 
 @GET
 @Path("/")
 public String listAll() {
  isUserInRole();
  return new Date()+": Yess!! "+jaxrsContext.getSecurityContext().getUserPrincipal();
 }

 private void isUserInRole() throws WebApplicationException {
  LOG.info("user = " + jaxrsContext.getSecurityContext().getUserPrincipal());
 }

}
The associated blueprint.xml configuration:



    
    <ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]"/>

    
        
            <ref component-id="customerSvc"/>
          
        
            <ref component-id="authenticationFilter"/>
        
    

    <bean id="customerSvc" class="ch.keller.servicemix.restws.server.CustomerService"/>
 
    
         <property name="contextName" value="karaf"/>
    
        
    
        
     users = $[karaf.base]/etc/users.properties
        
    
 
    
    
        <bean class="org.apache.karaf.jaas.modules.properties.PropertiesBackingEngineFactory" />
    

The format of the properties in users.properties is as follows, with each line defining a user, its password and associated roles:
user=password[,role][,role]...
And finally, the Maven pom.xml build script:

 4.0.0
 ch.keller.servicemix
 restws
 0.0.1-SNAPSHOT
 bundle

 
     2.6.8
     2.3.5
 

 
  
    org.apache.cxf
   cxf-bundle
   provided
   ${cxf-version}
  
 

 
  
   
    org.apache.felix
    maven-bundle-plugin
    true
    ${felix-version}
    
     
      ${project.artifactId}
      ${project.description}
      
       org.apache.karaf.jaas.config,  
       org.apache.karaf.jaas.boot.principal,
       org.eclipse.jetty.plus.jaas,
       org.apache.karaf.jaas.boot,
       *
       
      
        ch.keller.servicemix.restws.server
      
      
    
   
    
 


Especially important is the import-package section that guarantees that no java.lang.ClassNotFoundException is thrown during runtime:

    org.apache.karaf.jaas.config,  
    org.apache.karaf.jaas.boot.principal,
    org.eclipse.jetty.plus.jaas,
    org.apache.karaf.jaas.boot,
    *

Eclipse with Eclemma: java.lang.NoClassDefFoundError: oracle/security/pki/OracleWallet

Trying to determine the code coverage of my JUnit 4 tests with EclEmma an java.lang.NoClassDefFoundError was thrown. As we all love Java stack traces, here a short excerpt:
java.lang.NoClassDefFoundError: oracle/security/pki/OracleWallet
 at java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Class.java:169)
 at org.hibernate.connection.DriverManagerConnectionProvider.configure(DriverManagerConnectionProvider.java:57)
 at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
 at
 ...
What does my JUnit Test wants from the OracleWallet? The application uses JDBC for the access of the Oracle DB, but OracleWallet is never directly used in my application. Without Eclemma the tests are running successfully. Not nice.

This seems to be a known problem which is fixed in EclEmma 2.1.3, see http://sourceforge.net/p/eclemma/bugs/108/. If you don't want (or are not allowed...) to update, then the workaround is to exclude oracle.* from the coverage agent in the Code Coverage preferences, see http://www.eclemma.org/userdoc/preferences.html.

Saturday, June 15, 2013

Setup AppDynamics for FUSE ESB / Apache ServiceMix in 5 Minutes

AppDynamics  is a powerful tool for the analysis of distributed Java and .NET applications. As it has only low overhead costs (according to the vendor < 2%), it can also be used in production environments.

I use JBoss Fuse 6.0.0 on MacOS. But the setup is similar on other operation systems.
Follow theses steps:
  1. Download AppDynamics Lite Java version from http://www.appdynamics.com/. Name and E-Mail address must be provided (and normally you will be contacted by the vendor...).
  2. Unzip the downloaded ZIP file AppDynamicsLite.zip to your desired installation directory :
    unzip AppDynamicsLite.zip -d <APP_DYNAMICS_HOME>
    
  3. Go to the installation directory:
        cd <APP_DYNAMICS_HOME>
    
  4. Unzip the viewer package:
        unzip LiteViewer.zip
    
  5. Enter the viewer directory:
        cd LiteViewer
    
  6. Start the viewer:
        java -jar adlite-viewer.jar
    
  7. Open URL http://localhost:8990/ with your browser. Default user is admin with password admin. You see an empty dashboard.
  8. If you monitor an OSGI runtime with AppDynamics you have to extend the boot delegation parameter of FUSE ESB. SSee http://litedocs.appdynamics.com/display/ADLite/OSGi+Infrastructure for further explanations. As I use Felix, I have to add com.singularity.* to the org.osgi.framework.bootdelegation property. For easier upgrade of FUSE ESB, I do not edit /etc/config.properties but /etc/custom.properties. It is important that you don't forget to add all default values. And of course these values may change if you upgrade your FUSE ESB installation. Finally, I add following line to /etc/custom.properties:
        org.osgi.framework.bootdelegation=com.singularity.*,org.osgi.framework.bootdelegation=org.apache.karaf.jaas.boot,sun.*,com.sun.*,javax.transaction,javax.transaction.*,org.apache.xalan.processor,org.apache.xpath.jaxp,org.apache.xml.dtm.ref,org.apache.xerces.jaxp.datatype,org.apache.xerces.stax,org.apache.xerces.parsers,org.apache.xerces.jaxp,org.apache.xerces.jaxp.validation,org.apache.xerces.dom
    
    If your are not sure which OSGI framework you use, you can query your configuration in your Karaf console with
        shell:info
    
  9. Configure AppDynamics agent for FUSE ESB. E.g., set $KARAF_OPTION in your shell:
        export KARAF_OPTS="$KARAF_OPTS -javaagent:<APP_DYNAMICS_HOME>/javaagent.jar"
    
    Or alternatively, add following statement to your start script /bin/karaf:
        KARAF_OPTS="$KARAF_OPTS -javaagent:<APP_DYNAMICS_HOME>/javaagent.jar"
    
  10. Start your FUSE ESB (in the same shell where you set $KARAF_OPTIONS):
        cd <FUSE_ESB_HOME>/bin/fuse
    
  11. Create some traffic on your FUSE ESB, e.g. invoke a web service etc.
  12. Go back to your AppDynamics viewer browser window at http://localhost:8990/ and you should see some business transactions.

  13. Finito.

Friday, June 7, 2013

FUSE ESB / Apache ServiceMix Worries...

Starting JBOSS FUSE ESB and received a million error messages in the log (short extract):

[510]% ./fuse
Please wait while JBoss Fuse is loading...
 29% [====================>                                                   ]ERROR: Bundle org.ops4j.pax.web.pax-web-spi [97] Error starting mvn:org.ops4j.pax.web/pax-web-spi/1.1.11 (org.osgi.framework.BundleException: Uses constraint violation. Unable to resolve bundle revision org.ops4j.pax.web.pax-web-spi [97.0] because it is exposed to package 'javax.servlet' from bundle revisions org.apache.geronimo.specs.geronimo-servlet_3.0_spec [269.0] and org.mortbay.jetty.servlet-api [263.0] via two dependency chains.

Chain 1:
  org.ops4j.pax.web.pax-web-spi [97.0]
    import: (&(osgi.wiring.package=javax.servlet)(version>=2.3.0)(!(version>=3.0.0)))
     |
    export: osgi.wiring.package=javax.servlet
  org.apache.geronimo.specs.geronimo-servlet_3.0_spec [269.0]

Chain 2:
  org.ops4j.pax.web.pax-web-spi [97.0]
    import: (&(osgi.wiring.package=org.ops4j.pax.web.service)(version>=1.1.11))
     |
    export: osgi.wiring.package=org.ops4j.pax.web.service; uses:=org.osgi.service.http
  org.ops4j.pax.web.pax-web-api [99.0]
    import: (&(osgi.wiring.package=org.osgi.service.http)(version>=1.0.0)(!(version>=2.0.0)))
     |
    export: osgi.wiring.package=org.osgi.service.http; uses:=javax.servlet.http
  osgi.cmpn [273.0]
    import: (osgi.wiring.package=javax.servlet.http)
     |
    export: osgi.wiring.package=javax.servlet.http; uses:=javax.servlet
    export: osgi.wiring.package=javax.servlet
  org.mortbay.jetty.servlet-api [263.0])

  ...

WTF? Deleted $FUSE_HOME/data directory, started FUSE again, and the errors are gone. It's a pain.

JBoss FUSE ESB vs. Apache ServiceMix vs. Apache Karaf vs. Apache Felix

What is JBoss FUSE ESB? And what is its relation to OSGI, Apache Felix, Eclipse Equinox, Apache Karaf and Apache ServiceMix?
  • Felix and Equinox are both OSGI core runtimes
  • Karaf is the ServiceMix Kernel and provides a "distribution" based on Felix or Equinox by adding features such as an admin console and blueprint configuration.
  • ServiceMix is an integration container aka ESB powered by OSGI unifying the features of ActiveMQ, Camel, CXF, and Karaf (and other)
  • JBoss Fuse ESB is an ESB based on ServiceMix adding bug fixes and extended documentation

Sources:

Sunday, April 21, 2013

Migrating Plug-in Configuration when updating Eclipse Release

I just downloaded the latest Eclipse Juno Release with the latest fixes etc. But how to migrate my plugins from my "old" Eclipse to the "new" one?

1. Export

First, you must export your plug-ins from your "old" Eclipse installation as follows:
1.0 Start your "old" Eclipse instance
1.1 Package explorer, right mouse click, choose Export

1.2 Choose Install: Installed Software Items to File

1.3 Select All and export to p2f file (remember the file path, as you will import this file into your "new" Eclipse instance)



2. Import

After exporting, you must import the exported p2f file to your "new" Eclipse installation as follows:
2.0 Shutdown the "old" Eclipse instance if you want to use the same workspace as used for the export and start your "new" Eclipse instance
2.1 Package explorer, right mouse click, choose Import

2.2 Choose Install: Install Software Items from File

2.3 Select your exported p2f file (see step 1.3 above)
2.4 Select All and Finish

That's it. Let me know if this was helpful!

Monday, October 22, 2012

JAVA_HOME setting on MacOS

I just downloaded the latest Java Update 1.7.09 for MacOS and installed it. And as usual, I had to fix the JAVA_HOME environmental property, so that all my Maven etc. tools still worked properly. In ~/.bash_profile, I added/updated following entries:
export JAVA_HOME6=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
export JAVA_HOME7=/Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home
export JAVA_HOME=$JAVA_HOME7
export PATH=$JAVA_HOME/bin:$PATH
I use JAVA_HOME6 and JAVA_HOME7 so that I can easily switch the standard Java version.

But, stop, stop, there must be a better way to do that, so that I don't have to update these lines after every Java download. And actually it is by using the not-so-well-known-but-very-useful command java_home:
The java_home command returns a path suitable for setting the JAVA_HOME environment variable. It determines this path from the user's enabled and preferred JVMs in the Java Preferences application. Additional constraints may be provided to filter the list of JVMs available. [...] The path is printed to standard output.
On my machine, java_home prints following path to the STDOUT:
[561]% /usr/libexec/java_home --version 1.7
/Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home
So, I can change my .bash_profile as follows:
export JAVA_HOME6=`/usr/libexec/java_home --version 1.6`
export JAVA_HOME7=`/usr/libexec/java_home --version 1.7`
export JAVA_HOME=$JAVA_HOME7
export PATH=$JAVA_HOME/bin:$PATH
On my machine, my Java environmental parameters becomes:
[555]% env | grep JAVA
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home
JAVA_HOME6=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
JAVA_HOME7=/Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home
Finito.