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...