Expanding your horizons on JVM with Kotlin

The power of Java ecosystem lies in the Java Virtual Machine (JVM) which runs variety of programming languages which are better suitable for some tasks than Java. One relatively new JVM language is Kotlin which is statically typed programming language that targets the JVM and JavaScript. You can use it with Java, Android and the browser and it’s 100% interoperable with Java. Kotlin is open source (Apache 2 License) and developed by a team at JetBrains. The name comes from the Kotlin Island, near St. Petersburg. The first officially considered stable release of Kotlin v1.0 was released on February 15, 2016.

Why Kotlin?

“Kotlin is designed to be an industrial-strength object-oriented language, and to be a better language than Java but still be fully interoperable with Java code, allowing companies to make a gradual migration from Java to Kotlin.” – Kotlin, Wikipedia

Kotlin’s page summaries the question “Why Kotlin?” to:

  • Concise: Reduce the amount of boilerplate code you need to write.
  • Safe: Avoid entire classes of errors such as null pointer exceptions.
  • Versatile: Build server-side applications, Android apps or frontend code running in the browser. You can write code in Kotlin and target JavaScript to run on Node.js or in browser.
  • Interoperable: Leverage existing frameworks and libraries of the JVM with 100% Java Interoperability.

“You can write code that’s more expressive and more concise than even a scripting language, but with way fewer bugs and with way better performance.” – Why Kotlin is my next programming language

One of the obvious applications of Kotlin is Android development as the platform uses Java 6 although it can use most of Java 7 and some backported Java 8 features. Only the recent Android N which changes to use OpenJDK introduces support for Java 8 language features.

For Java developers one significant feature in Kotlin is Higher-Order Functions, function that takes functions as parameters, which makes functional programming more convenient than in Java. But in general, I’m not so sure if using Kotlin compared to Java 8 is as much beneficial. It smooths off a lot of Java’s rough edges, makes code leaner and costs nothing to adopt (other than using IntelliJ IDEA) so it’s at least worth trying. But if you’re stuck with legacy code and can’t upgrade from Java 6, I would jump right in.

Learning Kotlin

Coming from Java background Kotlin at first glance looks a lot leaner, elegant, simpler and the syntax is familiar if you’ve written Swift. To get to know the language it’s useful to do some Kotlin Examples and Koans which get you through how it works. They also have “Convert from Java” tool which is useful to see how Java classes translate to Kotlin. For mode detailed information you can read the complete reference to the Kotlin language and the standard library.

If you compare Kotlin to Java you see that null references are controlled by the type system, there’s no raw types, arrays are invariant (can’t assign an Array to an Array) and there’s no checked exceptions. Also semicolons are not required, there’s no static members, non-private fields or wildcard types.

And what Kotlin has that Java doesn’t have? For starters there’s null safety, smart casts, extension functions and lots of things Java just got in recent versions like Null safety, streams, lambdas ( although which are “expensive”). On the other hand Kotlin targets Java 6 bytecode and doesn’t use some of the improvements in Java 8 like invoke-dynamic or lambda support. Some of JDK7/8 features are going to be included in Standard Library in 1.1 and in the mean time you can use small kotlinx-support library. It provides extension and top-level functions to use JDK7/JDK8 features such as calling default methods of collection interfaces and use extension for AutoCloseable.

And you can also call Java code from Kotlin which makes it easier to write it alongside Java if you want to utilize it in existing project and write some part of your codebase with Kotlin.

The Kotlin Discuss is also nice forum to read experiences of using Kotlin.

Tooling: in practice IntelliJ IDEA

You can use simple text editors and compile your code from the command line or use build tools such as Ant, Gradle and Maven but good IDEs make the development more convenient. In practice, using Kotlin is easiest with JetBrains IntelliJ IDEA and you can use their open source Community edition for free. There’s also Eclipse plugin for Kotlin but naturally it’s much less sophisticated than the IntelliJ support.

Example project

The simplest way to start with Kotlin application is to use Spring Boot’s project generator, add your dependencies, choose Gradle or Maven and click on “Generate Project”.

There are some gotchas with using Spring and Kotling together which can be seen from Spring + Kotlin FAQ. For example by default, classes are final and you have to mark them as “open” if you want the standard Java behaviour. This is useful to know with @Configuration classes and @Bean methods. There’s also Kotlin Primavera which is a set of libraries to support Spring portfolio projects.

For example Spring Boot + Kotlin application you should look at Spring.io writeup where they do a geospatial messenger with Kotlin, Spring Boot and PostgreSQL

What does Kotlin look like compared to Java?
Simple example of using Java 6, Java 8 and Kotlin to filter a Map and return a String. Notice that Kotlin and Java 8 are quite similar.

# Java 6
String result = "";
for (Map.Entry<Integer, String> entry : someMap.entrySet()) {
	if("something".equals(entry.getValue())){
		result += entry.getValue();
}
 
# Java 8
String result = someMap.entrySet().stream()
		.filter(map -> "something".equals(map.getValue()))
		.map(map->map.getValue())
		.collect(Collectors.joining());
 
# Kotlin
val result = someMap
  .values
  .filter { it == "something" }
  .joinToString("")
 
# Kotlin, shorter 
val str = "something"
val result = str.repeat(someMap.count { it.value == str })
 
# Kotlin, more efficient with large maps where only some matching.
val result = someMap
  .asSequence()
  .map { it.value }
  .filter { it == "something" }
  .joinToString("")

The last Kotlin example makes the evaluation lazy by changing the map to sequence. In Kotlin collections map/filter methods aren’t lazy by default but create always a new collection. So if we call filter after values method then it’s not as efficient with large maps where only some elements are matching the predicate.

Using Java and Kotlin in same project

To start with Kotlin it’s easiest to mix it existing Java project and write some classes with Kotlin. Using Kotlin in Maven project is explained in the Reference and to compile mixed code applications Kotlin compiler should be invoked before Java compiler. In maven terms that means kotlin-maven-plugin should be run before maven-compiler-plugin.

Just add the kotlin and kotlin-maven-plugin to your pom.xml as following

<dependencies>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib</artifactId>
        <version>1.0.3</version>
    </dependency>
</dependencies>
 
<plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <version>1.0.3</version>
    <executions>
        <execution>
            <id>compile</id>
            <phase>process-sources</phase>
            <goals> <goal>compile</goal> </goals>
        </execution>
        <execution>
            <id>test-compile</id>
            <phase>process-test-sources</phase>
            <goals> <goal>test-compile</goal> </goals>
        </execution>
    </executions>
</plugin>

Notes on testing

Almost everything is final in Kotlin by default (classes, methods, etc) which is good as it forces immutability, less bugs. In most cases you use interfaces which you can easily mock and in integration and functional tests you’re likely to use real classes, so even then final is not an obstacle. For using Mockito there’s Mockito-Kotlin library https://github.com/nhaarman/mockito-kotlin which provides helper functions.

You can also do better than just tests by using Spek which is a specification framework for Kotlin. It allows you to easily define specifications in a clear, understandable, human readable way.

There’s yet no static analyzers for Kotlin. Java has: FindBugs, PMD, Checkstyle, Sonarqube, Error Prone, FB infer. Kotlin has kotlinc and IntelliJ itself comes with static analysis engine called the Inspector. Findbugs works with Kotlin but detects some issues that are already covered by the programming language itself and are impossible in Kotlin.

To use Kotlin or not?

After writing some classes with Kotlin and testing converting existing Java classes to Kotlin it makes the code leaner and easier to read especially with data classes like DTOs. Less (boilerplate) code is better. You can call Java code from Kotlin and Kotlin code can be used from Java rather smoothly as well although there are some things to remember.

So, to use Kotlin or not? It looks a good statically-typed alternative to Java if you want to expand your horizons. It’s pragmatic evolution to Java that respects the need for good Java integration and doesn’t introduce anything that’s terribly hard to understand and includes a whole bunch of features you might like. The downsides what I’ve come across are that tooling support is kind of limited, meaning in practice only IntelliJ IDEA. Also documentation isn’t always up to date or updated when the language evolves and that’s also an issue when searching for examples and issues. But hey, everything is fun with Kotlin :)

Patching RichFaces 3.3.3 AJAX.js for IE11

Couple of years ago I wrote about patching RichFaces 3.3.3 AJAX.js for IE9 and as the browser world has moved on, it’s now time to patch RichFaces 3.3.3 AJAX.js for Internet Explorer 11. Of course you could update your web application to JSF 2 and RichFaces 4 or PrimeFaces but it’s neither trivial nor free. The issue with RichFaces 3.3.3 still stands, development has moved to 4.x version and they’ve dropped support for the older versions although at least IE issues could be easily fixed. Fortunately patching RichFaces AJAX.js is relatively easy.

The problem with Internet Explorer 11 is that although you upgraded Sarissa Framework and patched RichFaces AJAX.js file for IE 9 it just isn’t enough anymore as IE 11 uses different User-agent string and disguises itself as “like Gecko”. The User-agent string in Win 8.1 for IE11 is “Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko”. The issue is also discussed on JBoss Forums and on Stack Overflow.

The different User-agent string breakes the “rerender” after Ajax Request. For example using a4j:function in combination with “rerender” is not working on IE 11 and the problem is that after Ajax request the result XML can’t be correctly append to the body. Also the rerendering is abnormal for h:inputTextarea, rich:modalPanel, h:inputTextarea and rich:calendar.

Fortunately the fix is simple as RicFaces issue RF-13443 tells.

Patching RichFaces 3.3.3 AJAX.js for IE 11

Step 1: Do the “Upgrading Sarissa Framework and patching RichFaces AJAX.js file” steps in my Patching RichFaces 3.3.3 AJAX.js for IE9 article.

Step 2: Edit the AJAX_IE9fix.js file you just created and add IE 11 checking to Sarissa._SARISSA_IS_IE and Sarissa._SARISSA_IS_IE9. The changed lines should look like the following:

Sarissa._SARISSA_IS_IE = (document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1) || (navigator.userAgent.toLowerCase().indexOf("like gecko") > -1 && navigator.userAgent.toLowerCase().indexOf("11.") > -1);
 
Sarissa._SARISSA_IS_IE9 = Sarissa._SARISSA_IS_IE && (parseFloat(navigator.appVersion.substring(navigator.appVersion.indexOf("MSIE")+5))) >= 9 || (navigator.userAgent.toLowerCase().indexOf("like gecko") > -1 && navigator.userAgent.toLowerCase().indexOf("11.") > -1);

If all fails you can try to tell IE 11 to emulate IE 10 with adding X-UA-Compatible meta tag to head.

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE10"/>

The other thing I noticed with RichFaces 3.3.3 and modern browsers is that if you use ui:fragment which contains rich:suggestionbox and rerender it, the suggestionbox doesn’t work correctly. It gives an error: SCRIPT5007: Unable to get property 'parentNode' of undefined or null reference. For now I didn’t have time to figure out the issue and just changed my page structure and function.

Although it’s 2015 using JSF 1.2 and RichFaces 3.3.3 is still working quite nicely :)

Using Bacon2D with Sailfish OS

Sailfish OS development for Jolla is quite versatile and you can use QML plugins to enhance your application. But if you’ve used a QML module which isn’t approved in Harbour and want to distribute your application via Jolla Store, you’ve to do some extra steps with it. Lately I ported Ubuntu Phone’s Falldown game for Sailfish OS and it uses Bacon2D framework to ease 2D game development. Bacon2D isn’t allowed in Harbour so I had to patch it to accept custom namespace and either package the dynamically linked library with my app’s RPM or use statically linked Bacon2D with my app. Here are my notes about it.

The examples will be with my Falldown game project and the code can be found on GitHub. The steps shown below are not the optimal way of doing things as you could streamline the process by including Bacon2D build to your project build and in RPM spec patch the needed files. Will see if I get around doing that and automate things.

Building Bacon2D for Sailfish OS

Bacon2D is a framework to ease 2D game development, providing ready-to-use QML elements representing basic game entities needed by most of games. Bacon2D uses Box2D, a 2D rigid body simulation engine for games. Box2D lets you make objects move in realistic ways and make the game world more interactive.

You can use Bacon2D in your Sailfish OS project by using it as dynamically or statically linked library. The easiest way is to just use the statically linked version so it’s statically compiled into your project. But it’s almost as easy to build the dynamically linked library.

The other issue is getting the Bacon2D built such way that you can use it in your project and submit your application to Jolla Store. As Bacon2D plugin isn’t allowed in Harbour you’ve to patch it to your own namespace, e.g harbour.falldown.bacon2d.

The next chapters cover the three different ways to build and use Bacon2D with Sailfish OS.

Get Bacon2D framework

Start with adding the Bacon2D repository to your project’s Git repository as submodule.

$ git submodule add https://github.com/Bacon2D/Bacon2D.git

Now the Bacon2D project files are in e.g. falldown/Bacon2D and falldown directory will be our base.

Now you’re ready to build and use Bacon2D with three optional ways:

After I got the needed things to work, I used the Option 3 way to get Bacon2D included in my application and hopefully it gets approved to Jolla Store.

Option 1: Using statically linked Bacon2D

In your project’s project file e.g. harbour-falldown.pro add to the top of the file include clause for including Bacon2D statically

include(./Bacon2D/src/Bacon2D-static.pri)

In your project’s main.cpp include plugins.h and register types before loading QML resources.

#include <plugins.h>
 
Plugins plugins;
plugins.registerTypes("Bacon2D");

Build your project in Qt Creator by selecting Build->Release, Deploy->Deploy as RPM Package and then running Build -> Clean, Build, Deploy.

Your Bacon2D powered app should now launch in your phone.

Option 2: Using dynamically linked Bacon2D

Open Bacon2D/Bacon2D.pro with Qt Creator and disable the test and examples subdirectories.

SUBDIRS += src

Build Bacon2D for Armv7: Select Kit – MerSDK-SailfishOS-armv7hl – Release – Deploy by copying binaries. The build will fail with “Error 127” but the libbacon2dplugin.so is built so you can use it now.

Copy the “build-Bacon2D-MerSDK_SailfishOS_armv7hl-Release/src/imports” directory which contains QML files and libbacon2dplugin.so to your project’s lib directory, e.g. falldown/lib.

$ cp -r build-Bacon2D-MerSDK_SailfishOS_armv7hl-Release/src/imports/Bacon2D lib

In e.g. harbour-falldown.pro add the lib directory to be added inside RPM.

DEPLOYMENT_PATH = /usr/share/$${TARGET}
lib.files += lib
lib.path = $${DEPLOYMENT_PATH}
INSTALLS += lib

In your main.cpp add import path to Bacon2D files.

view->engine()->addImportPath(SailfishApp::pathTo("qml/imports/").toLocalFile());

In Qt Creator select Build->Release, Deploy->Deploy as RPM Package. Run Build -> Clean, Build, Deploy.

Your Bacon2D powered app for Sailfish OS should now launch in Jolla.

Option 3: Using statically linked Bacon2D the Harbour way

Including statically linked Bacon2D to be built with you Sailfish OS application can be done different ways and I chose not to write my own plugins.cpp to register QML types and just patched the plugins.cpp which Bacon2D provides.

In harbour-falldown.pro add to the top of the file include clause for including Bacon2D statically

include(./Bacon2D/src/Bacon2D-static.pri)

Patch Bacon2D Bacon2D/src/plugins.cpp to accept e.g. harbour.falldown.bacon2d namespace. Change every qmlRegisterType line from “Bacon2D” to your namespace.

qmlRegisterType<Layer>("harbour.falldown.bacon2d", 1, 0, "Layer");

In your project’s src/main.cpp include plugins.h and register types before loading QMLresources.

#include <plugins.h>
 
Plugins plugins;
plugins.registerTypes("harbour.falldown.bacon2d");

Put Bacon2D QML files under e.g. qml/components and change them to import e.g. harbour.falldown.bacon2d 1.0. Somehow I didn’t get the Bacon2D type to work which defines enums.

Build your project in Qt Creator by selecting Build->Release, Deploy->Deploy as RPM Package and then running Build -> Clean, Build, Deploy.

Your Bacon2D powered app should now launch in your phone.

Option 4: Using dynamically linked Bacon2D the Harbour way

You can link against shared libraries which ships with your Sailfish OS app in the RPM but because of Harbour rules you have to install the library under e.g. /usr/share/harbour-falldown/lib.

But before you can use the dynamically linked Bacon2D for Sailfish OS app intended to be distributed via Jolla Harbour you have to patch Bacon2D to accept e.g. harbour.falldown.bacon2d namespace and build the library.

In Bacon2D project change the following files.

Bacon2D/Bacon2D.pro

PROJECT_NAME = harbour.falldown.bacon2d

Bacon2D/src/src.pro

TARGETPATH = harbour/falldown/bacon2d
DESTDIR = $$OUT_PWD/imports/harbour/falldown/bacon2d/

Bacon2D/src/plugins.cpp

qmlRegisterType<Layer>("harbour.falldown.bacon2d", 1, 0, "Layer");

Bacon2D/src/qmldir

module harbour.falldown.bacon2d

In Bacon2D/src directory change every QML file to import e.g. harbour.falldown.bacon2d 1.0

Build Bacon2D with Qt Creator for Armv7: Kit – MerSDK-SailfishOS-armv7hl – Release – Deploy by copying binaries

Copy Bacon2D QML files and libbacon2dplugin.so under lib directory and to the structure which match you import namespace, e.g.: lib/harbour/falldown/bacon2d/.

$ cp -r build-Bacon2D-MerSDK_SailfishOS_armv7hl-Release/src/imports/harbour lib

In your project’s project file, e.g. harbour-falldown.pro add the lib directory to be added inside RPM

DEPLOYMENT_PATH = /usr/share/$${TARGET}
lib.files += lib
lib.path = $${DEPLOYMENT_PATH}
INSTALLS += lib

In your spec file, e.g. rpm/harbour-falldown.spec add following exclude as Harbour RPM packages should not provide anything.

# >> macros
%define __provides_exclude_from ^%{_datadir}/.*$
# << macros

Also to use QML modules which ships together with the application but you have to prefix the name of the imports with e.g. “harbour.falldown.bacon2d”. And you have to install them under /usr/share/harbour-falldown (loadable QML plugins or the QML files).

In src/main.cpp add import path to Bacon2D QML files and plugin before loading qml resources.

view->engine()->addImportPath(SailfishApp::pathTo("lib/").toLocalFile());

Build your project in Qt Creator by selecting Kit – MerSDK-SailfishOS-armv7hl – Release – Deploy – Deploy as RPM Package and then running Clean, Build, Deploy.

Your Bacon2D powered app should now launch in your phone.

Starting iOS development with Swift

Mobile application development differs between platforms and after doing couple of applications for the Sailfish OS powering Jolla phone it was finally time to see what other platforms have to provide. I develop Java applications at work so it was logical to look into iOS and learn some Swift. The Internet is full of resources of how to start developing for iOS and here’s my take to the topic. Now I just need an iPhone to run my app on a real device :)

Getting started

Coming from the Java EE and Web application world it’s good to read some documentation about mobile application development for iPhone and iOS before starting to code. You need to learn the basics concepts about iOS platform and Swift language and good starting point is to check Apple’s resources for developers and iOS developer library and read the guide how to start developing iOS apps (although it’s with Objective-C). To learn Swift you can read guide to Swift language or if you like books there’s also The Swift Programming Language book.

You can also start learning iOS development with several free or paid online courses. Coding with Chris “how to make an iPhone app” series of videos is a good starting point although it’s designed for people who have no programming experience. It provides nice overview to the tools and how to start developing. You can also follow the App Development: Teaching Swift by Apple Education with code examples or if you’ve the money and need diploma see the Udemy course for iOS developers or Udacity’s iOS developer Nanodegree.

It’s also good to read Human Interface Guidelines for iOS-based devices although the guidelines don’t provide any practical examples. It’s a good resource to learn how iOS applications should work, tells you how your app should look and behave and how to use the UI elements that UIKit provides. As I have done apps for Sailfish OS it was good to adapt my thinking to see things in the iOS way.

In practice the best way to learn is to just write code and experiment. Getting to know XCode and Interface Builder takes some time. After using Eclipse and IntelliJ IDEA for Java development both XCode and Apple’s graphical UI editor are somewhat confusing at first.

There’s also couple of iOS development newsletters to follow: iOS Dev Weekly, This Week In Swift. Also the In depth Mac and iOS articles archives is a good resource.

And if you’re using IRC there’s #cocoa-init channel on irc.freenode.net focused on asking and answering questions for beginning developers on iOS and OS X. For more general iOS development you can join #iphonedev channel on irc.freenode.net. To join them you need to register your nick.

Development in practice

Getting started with iOS can be challenging as Swift and Objective-C are used mainly only on Apple’s platform and it has its own names for almost everything. I haven’t yet gathered my own good practices so it’s great that you can read about iOS good practices from Futurice.

Basic tools

For iOS development your options with tools are somewhat limited as you need Mac computer running OS X (10.9.4 or later) for being able to run Apple Xcode and iOS SDK. The other option is to use JetBrains Appcode (99e) which is better (what I’ve understood). Xcode can be installed from Mac App Store and it comes with iOS SDK. Also although you can run your applications in iOS Simulator it helps to have a real device which helps you to understand how apps interact with users and what the look and feel should be. The documentation and examples gets you far but nothing beats to have first hand experience of the platform.

I found it beneficial to watch e.g. the Coding with Chris “how to make an iPhone app” series of videos for getting around XCode development environment.

Xcode and UI builder

Developing for iOS

iPhone applications can be written with Objective-C or with newer Swift programming language. Objective-C is built on top of the C programming language and provides object-oriented capabilities and a dynamic runtime. Swift in the other hand can be described as Objective without the C and is a replacement for the Objective-C language and works side-by-side with it. Wikipedia has good short description of Swift.

Although Swift is relatively new and what I’ve read isn’t quite as robust as Objective-C it’s good starting point for developing iOS apps. Having used some Objective-C for OS X apps I wouldn’t recommend it to anyone if you don’t actually need it.

iOS platform

Apple’s operating system for iPhone, iOS, provides many frameworks for developers and as a developer you’ve to decide which version to target as it affects your application and capabilities. Apple’s iOS developer page provides short overview of what it has to offer. The current version is iOS 8 and i.a. Shinobicontrols has written iOS 8 Day by Day eBook which consists of 39 blog posts covering the most significant features available to developers in iOS 8.

As a developer you have to choose which version of iOS you target and whether your app is universal or only for iPhone or iPad as it affects your code and potential users. Do you need the new features in iOS 8 or is iOS 7 enough and is it worth to make solutions to fit both versions? And do you need different user interface for bigger screen in iPad or is universal version enough? iOS 8 is supported on iPhone 4s or newer and newer iPads and what I read about 72% of devices are using iOS 8 and 25% are on iOS 7. So, I think it’s enough to target iOS 8 as it provides you more options how to implement your app.

Developing with Swift

The best way to get to know Swift is just read some code, watch tutorials and of course write code. To learn Swift you can read guide to Swift language and you can watch from Youtube e.g. rm2kdev series about Swift starting from the basics and example of doing a To Do List app.

One nice element of the Swift system which helps you to get hang of it, is its ability to be cleanly debugged and run within the development environment, using a read–eval–print loop (REPL). It gives you interactive properties more in common with the scripting capabilities of Python than traditional systems programming languages. It’s useful to play with Swift in Xcode Playground and see what your code does.

Knowing Swift language is just one part and the bigger part in my opinion is to know how to use the UI elements that UIKit provides to create good user experience. When I started developing my app with Swift majority of time went to figuring out how to construct the user interface with Xcode UI builder and what the elements should be, not actually writing much code in Swift. User experience section in iOS Developer Library and UI Elements in iOS Human Interface Guidelines provide good starting points for reading about user experience but doesn’t help you much with coding especially when the sample codes are in Objective-C. Basic UI elements like “pull to refresh”, “swipe between views”, “split view” and “slide-out navigation” are more easily found by googling.

We all have our own ways to learn new platform and programming language and I find it beneficial to just create small application which experiment with different concepts and interactions. I’m gathering my own experiments with iOS technologies to GitHub and building a news reader application for High.fi on the way.

So, what are you waiting for? Download Xcode and start developing your own app for iOS :)

Summary

Documentation

iOS 8

Other resources

Courses and guides

Disabling Derby in Oracle WebLogic 12c

Oracle WebLogic has some interesting traits to help developers frustrate. From Weblogic 10.3.4 and above the Apache Derby Database is included in the installation. That’s fine but from 12.1.2 release it also starts automatically which is usually unwanted, useless and waste of resources. Previous versions of WebLogic didn’t automatically start the Derby database.

Fortunately you can disable it as basically there is a simple IF statement in the “$WL_DOMAIN_HOME$\bin\setDomainEnv.cmd” file:

@REM Set DERBY_FLAG, if derby is available.
 
if exist %WL_HOME%\common\derby\lib\derby.jar (
    set DERBY_FLAG=true
)

If you want to prevent Derby form starting you have three options:

  • Rename “derby.jar” to something else
  • Delete the IF statement from start-up script
  • Set the DERBY_FLAG to false in the startWeblogic.cmd script

I couldn’t find Oracle’s documentation about Derby in Weblogic but those four options seems to work. I prefer the third option which is quite easy to configure. (via Oracle Community)

In my “$WL_DOMAIN_HOME$\bin\startWebLogic.cmd” I added

...
@REM Call setDomainEnv here.
 
@REM Disabling Derby
set DERBY_FLAG = false
...

Using the WebLogic 12c Maven Plug-In for Deployment

Using the WebLogic 12c 12.1.2 Maven plug-In for deployment is much easier and quicker than going through the WebLogic Server’s AdminServer and Oracle Documentation provides good examples how to do it. The weblogic-maven-plugin provides enhanced functionality to install, start and stop servers, create domains, execute WLST scripts, and compile and deploy applications.

The weblogic-maven-plugin plug-in is provided as a pre-built JAR file and accompanying pom file. In short, installing and configuring the WebLogic 12c Maven sync plug-in contains following steps:

Open command prompt and run commands:

cd D:\oracle\wls12120\oracle_common\plugins\maven\com\oracle\maven\oracle-maven-sync\12.1.2
mvn install:install-file -DpomFile=oracle-maven-sync.12.1.2.pom -Dfile=oracle-maven-sync.12.1.2.jar
mvn com.oracle.maven:oracle-maven-sync:push -Doracle-maven-sync.oracleHome=D:\oracle\wls12120

You can validate whether you have successfully installed the plug-in using the Maven help:describe goal.

mvn help:describe -DgroupId=com.oracle.weblogic -DartifactId=weblogic-maven-plugin -Dversion=12.1.2-0-0

And you’re ready to deploy with Maven. A lot more easier than generating the WebLogic 11g R2 Maven Plug-in where you had to i.a. build the jar by yourself.

The Maven plug-in can be used e.g. from application’s POM file and be bound to some phase of the Maven life cycle. For example it can be bound to “install” phase and every time you run the “mvn install” command, the deployment plug-in is also called. In my opinion better way to use the plug-in is to add it as a profile so you can call it just when you want with command like “mvn clean install -Pdeploy-wls“.

Maven Project pom.xml File

<profile>
	<id>deploy-wls</id>
	<build>
		<plugins> 
			<plugin> 
				<groupId>com.oracle.weblogic</groupId>
				<artifactId>weblogic-maven-plugin</artifactId> 
				<version>12.1.2-0-0</version> 
				<configuration> 
					<adminurl>t3://localhost:7001</adminurl>
					<user>weblogic</user> 
					<password>weblogic123</password> 
					<upload>true</upload> 
					<targets>myServer</targets>
					<action>deploy</action> 
					<remote>false</remote> 
					<verbose>true</verbose> 
<source>${project.build.directory}/${project.build.finalName}.${project.packaging}</source> 
					<name>${project.build.finalName}</name> 
				</configuration> 
				<executions> 
					<execution> 
						<phase>install</phase> 
						<goals> 
							<goal>deploy</goal> 
						</goals> 
					</execution> 
				</executions> 
			</plugin> 
		</plugins> 
	</build>
</profile>

The user credentials in the POM file are provided as clear-text but for more security you can use secure configuration authentication mechanism which stores the user name and password in encrypted form in an external file, and then uses it to supply the user credentials with which to connect to the WebLogic Server domain, along with the key that was used to encrypt the file.

Patching RichFaces 3.3.3 AJAX.js for IE9

There are always some problems when working with 3rd party frameworks when the world moves forward but the framework you’re using doesn’t. After JSF 2 was released the RichFaces development moved to 4.x version and they dropped support for the older versions although many users are still using the older versions as it’s not trivial or free to update to JSF 2 & RichFaces 4. Now if users have problems with the older versions they just have to patch it themselves as the RichFaces team isn’t going to fix e.g. the IE9 issues.

The problem with Internet Explorer 9 is that with RichFaces 3.3.3.Final the Ajax components doesn’t work and there are errors shown in the JavaScript Console. For example when testing RichFaces Ajax demos the JavaScript is assigning A.outerHTML = new XMLSerializer().serializeToString(C) which gives the following error:

SCRIPT16386: No such interface supported

Fortunately it’s relatively easy to fix it for IE9 by patching the AJAX.js JavaScript file in RichFaces. The process is discussed in RichFaces’s RF-9485 -JIRA ticket and JBoss forum message. In short the patching for AJAX.js contains following steps.

Update 2013-06-13: If you want quick solutions and aren’t interested about how it’s done, you can get the patched AJAX.js from the RF-9485 ticket as Ken Clubok pointed out in the comments.

Upgrading Sarissa Framework and patching RichFaces AJAX.js file

Resources:

1) Instead of patching Sarissa as suggested in the ticket it’s better to upgrade Sarissa to 0.9.9.6 as it has some additional IE9 issues fixed.

Download Sarissa:
http://sourceforge.net/projects/sarissa/files/sarissa/Sarissa%200.9.9.6/sarissa-0.9.9.6.jar/download

Extract sarissa.js from the jar:
sarissa-0.9.9.6.jar/gr/abiss/js/sarissa/sarissa.js

Replace first part of AJAX.js (till EOF comment) or replace sarissa.js in richfaces souce resources.
richfaces-impl-3.3.3.Final.jar/org/ajax4jsf/javascript/scripts/AJAX.js or richfaces-ui-3.3.3.Final\framework\impl\src\main\javascript\ajaxjsf\

2) For richfaces-impl work in non-compatibility mode in IE9, A4J.AJAX.replacePage method should be fixed in RichFaces sources in AJAX.js or JSFAJAX.js because custom document.open method does not work in IE9 document mode.

Replace (line 2125 in AJAX.js, line 1121 in JFSAJAX.js)
	if(isIE) {  
With
	if(isIE&&!Sarissa._SARISSA_IS_IE9) {

3) You will also need to change or comment the next line in AJAX.js or JSFAJAX.js (richfaces-ui-3.3.3.Final\framework\impl\src\main\javascript\ajaxjsf\)

Replace (line 2119 in AJAX.js, line 1044 in JFSAJAX.js)
	LOG.debug("Hidden JSF state fields: "+idsSpan);
to
	LOG.debug("Hidden JSF state fields: ");//+idsSpan);

Otherwise you get the following error in IE9:

	SCRIPT438: Object doesn't support this property or method
	For this line 2648 in framework pack:
	LOG.debug("Hidden JSF state fields: "+Q);

4) Now you have patched AJAX.js and you can either build a new RichFaces Jar, replace the original AJAX.js in RichFaces Jar with the patched one or just override it in your html.

The easiest way is just include the patched AJAX.js file as the last script-include within HEAD and it will take control over the bundled version of RichFaces.

In your template.jspx or similar:

<html>
	<head>
	<a4j:loadScript src="/js/AJAX_IE9fix.js" />
	...
	</head>
	...

5) Done.

Other ways to fix IE9 compatibility issues has been discussed in tickets RF-10774 as forcing IE9 to use another document mode. Also suggested solutions are to implement a browser sniffer and tell the Sarissa library to use its own XMLSerializer when Internet Explorer 9 is detected and forcing IE9 to run in an emulated mode but neither of those worked for me.

JSF 1.2 and getting selected value from dropdown

JSF 1.2 has some weird features which you just have to know if you haven’t read the documents. One example is getting a value from h:selectOneMenu dropdown after onchange event. The first what comes to mind is to use binding attribute with RichFaces’ a4j:support for rerendering elements after the event but it doesn’t work like you thought it would. In some cases using the binding attribute works just fine but as the binding attribute should refer to a request scoped bean property, not a session scoped one, you might get “Duplicate id error” when switching pages back and forth.

Fortunately there is valueChangeListener in h:SelectOneMenu which you can trick to do almost the same. It is executed during Validations phase, before the “Update Model Values” phase and is intended to get a handle of both the old and new value so that you can do some business stuff based on the real change. However, you can use it to invoke actions on a dropdown change only by combining it with onchange="submit()" and immediate="true" and the selected value is to be obtained by ValueChangeEvent#getNewValue(). (StackOverflow, BalusC)

For example:

Jspx:
<h:selectOneMenu value="#{fooBean.object.value}" 
	valueChangeListener="#{fooBean.statusChanged}" 
	onchange="submit()" immediate="true">
	<f:selectItem itemLabel="" itemValue=""/>
	<f:selectItems value="#{fooBean.selectValuesList}"/>
</h:selectOneMenu>
 
Java:
public void statusChanged(ValueChangeEvent event) {
	if (event.getNewValue() != null && 
		StringUtils.hasText((String) event.getNewValue())) {
		// ... Do something with the new value
	}
}

The negative side of using onchange="submit()" is that the form is submitted, validated and you don’t get the same dynamic feeling like with a4j:support.

In JSF 2 things are easier as you don’t need the valueChangeListener and you can use the listener attribute of instead.

Exclude JQuery libraries from Eclipse’s JavaScript Validation

Eclipse likes to validate JavaScript when doing Dynamic Web Modules and thus may give you false positive validation errors on 3rd party JavaScript libraries like JQuery. Although you can turn off the validation altogether but better solution is to configure it to exclude files as Alexander shows us at Stackoverflow.

Eclipse Indigo (3.7) has the option to selectively remove some JavaScript sources from validation. The information about JavaScript source inclusion/exclusion is saved into .settings/.jsdtscope file.

  1. Right click your project
  2. Select Properties → JavaScript → Include Path
  3. Select Source tab
  4. Expand JavaScript source folder
  5. Highlight Excluded pattern
  6. Click Edit button
  7. Click Add button next to Exclusion patterns box
  8. You may use wildcard pattern, or click Browse button to add the source by name.
    • Exclude all JQuery files with pattern like: js/jquery-*

The configuration with JQuery files excluded from validation looks like this:

eclipse_exclude-javascript

Using RichFaces 3 dataScroller and dataTable -components

RichFaces provides some nice AJAX-components for Java Server Faces but the documentation and examples could be better. RichFaces has great documentation compared to some other frameworks but it could be better with adding a little bit of real world and down to earth examples. So here is one example of using RichFaces dataScroller and dataTable -components with custom CSS-styling, backingBean and JSF-page snippets using Richfaces 3.3.2.SR1 and JSF 1.2_12.

Using RichFaces dataScroller and dataTable components has a big negative property: they work nicely if the amount of data is small but when the row count reaches to thousands they become sluggish or stop working. The rich:dataScroller needs the complete datamodel being loaded into memory and only displays a part of it. Not very efficient if the rowcount exceeds 1000 or so.

Anyways here is some real world example. The icons used in the examples for dataScroller are from Crystal Project Icons.

JSF-page

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<h:form id="myForm">
    <rich:dataScroller styleClass="dataScroller" id="scroller" 
        for="resultTable" maxPages="15" fastStep="3"
        renderIfSinglePage="false" immediate="false" 
        binding="#{backingBean.scroller}" page="#{backingBean.scrollerPage}">
        <f:facet name="first" >
            <h:graphicImage id="firstImage" styleClass="scroller" 
            url="images/crystal/tab_first.png" alt="first"/>
        </f:facet>
        <f:facet name="last">
            <h:graphicImage id="lastImage" styleClass="scroller" 
                url="images/crystal/tab_last.png" alt="last"/>
        </f:facet>
        <f:facet name="previous">
            <h:graphicImage id="prevImage" styleClass="scroller" 
                url="images/crystal/tab_left.png" alt="previous"/>
            </f:facet>
        <f:facet name="next">
            <h:graphicImage id="nextImage" styleClass="scroller" 
                url="images/crystal/tab_right.png" alt="previous"/>
        </f:facet>
        <f:facet name="fastforward">
            <h:graphicImage id="ffImage" styleClass="scroller" 
                url="images/crystal/tab_fastf.png" alt="next"/>
        </f:facet>
        <f:facet name="fastrewind">
            <h:graphicImage id="frImage" styleClass="scroller" 
                url="images/crystal/tab_fastr.png" alt="next"/>
        </f:facet>
        <f:facet name="first_disabled" >
            <h:graphicImage id="firstImage_d" styleClass="scroller" 
                url="images/crystal/tab_first.png" alt="first"/>
        </f:facet>
        <f:facet name="last_disabled">
            <h:graphicImage id="lastImage_d" styleClass="scroller" 
                url="images/crystal/tab_last.png" alt="last"/>
        </f:facet>
        <f:facet name="previous_disabled">
            <h:graphicImage id="prevImage_d" styleClass="scroller" 
                url="images/crystal/tab_left.png" alt="previous"/>
        </f:facet>
        <f:facet name="next_disabled">
            <h:graphicImage id="nextImage_d" styleClass="scroller" 
                url="images/crystal/tab_right.png" alt="next"/>
        </f:facet>
        <f:facet name="fastforward_disabled">
            <h:graphicImage id="ffImage_d" styleClass="scroller" 
                url="images/crystal/tab_fastf.png" alt="next"/>
        </f:facet>
        <f:facet name="fastrewind_disabled">
            <h:graphicImage id="frImage_d" styleClass="scroller" 
                url="images/crystal/tab_fastr.png" alt="previous"/>
        </f:facet>
        <f:facet name="controlsSeparator">
            <h:outputText id="sep" value=" " />
        </f:facet>
</rich:dataScroller>
 
<rich:dataTable styleClass="resultTable" id="resultTable" 
    rows="10" rowClasses=",odd"  columnClasses="col"  
    value="#{backingBean.resultList}" binding="#{backingBean.resultData}" 
    var="h" sortMode="multi">
    <rich:column sortBy="#{h.desc}">
        <f:facet name="header">
            <h:outputText value="description" />
        </f:facet>
        <h:commandLink value="#{h.desc}"
            action="#{backingBean.showRowData}">
            <f:param name="selectedRow" value="#{h.desc" />
        </h:commandLink>
    </rich:column>
    <rich:column sortBy="#{h.value}">
        <f:facet name="header">
            <h:outputText value="value" />
        </f:facet>
        <h:outputText value="#{h.value}" />
    </rich:column>
</rich:dataTable>
</h:form>

Backing Bean

Create some variables for dataScroller and getters and setters for them:

1
2
3
4
5
6
7
8
// RichFaces dataScroller variables
private HtmlDatascroller scroller = new HtmlDatascroller();
private String scrollerPage = "";
 
// Getting the clicked row's data
public String showRowdata() {
  MyDataModel current = (myDataModel) getResultData().getRowData();
}

CSS styling

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* =RichFaces DataScroller
----------------------------------------------- */
.rich-datascr {font-size: 1.1em;border: 0;}
.rich-table-cell {font-size: 1.0em;}
.rich-table-sortable-header {font-size: 1.1em;font-weight: bold;}
td.rich-datascr-button {background-color: #fff;border: 0px solid #ccc;text-decoration: none;}
td.rich-datascr-button-dsbld {background-color: #fff;}
.rich-datascr-ctrls-separator {padding-right: 5px;}
.rich-dtascroller-table {background: #fff;border: 0;}
.scroller {display: block;background-color: #fff;border: 1px solid #ccc;padding: 3px 3px;margin: 0px 5px 5px 5px;text-decoration: none;}
.scroller:hover {background-color: #eee;}
td.rich-datascr-button-dsbld .scroller {background-color: #eee;}
td.rich-datascr-inact {font-size: 1.2em;color: #000;border: 0;}
td.rich-datascr-inact:hover {text-decoration: underline;}
td.rich-datascr-act {font-size: 1.2em;text-decoration: underline;}
td.rich-datascr-act {border: 0;font-weight: bold;}

Selecting All rows with JavaScript

Add to the JSF-page a new column which has the checkbox. We are using JavaScript to loop through the input fields which are after :tu -ending id-field.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<rich:column>
  <f:facet name="header">
    <h:panelGroup layout="block">
      <script type="text/javascript">
        //<![CDATA[
        // RichFaces datatable select all -checkbox
        function checkAllCheckboxesInTable( inputId, state ){
          var commonIdPart = inputId.substr(0, inputId.lastIndexOf(':'));
          var tableId = commonIdPart + ':tu'
          var tableElement = document.getElementById( tableId );
          var inputs = tableElement.getElementsByTagName('input');
          for (var i = 0; i <= inputs.length; i++){
            var input = inputs[i];
            if (input != undefined) {
              if( input.getAttribute('type') == 'checkbox' && state){
                input.setAttribute('checked', state);
              } else{
                input.setAttribute('checked', false);
                input.removeAttribute('checked');
              }
            }
          }
        }
        //]]>
      </script>
      <h:selectBooleanCheckbox id="t0" onclick="checkAllCheckboxesInTable( this.id, this.checked );">
        <a4j:support event="onchange" reRender="resultTable"/>
      </h:selectBooleanCheckbox>
    </h:panelGroup>
  </f:facet>
  <h:selectBooleanCheckbox id="t1" value="#{h.selected}" />
</rich:column>

Selecting All rows in backing bean

You can also check all the checkboxes from the backingBean but it has problems with table ordering and when the lists order changes the selection goes wrong.

Add to the JSF-page a new column:

1
2
3
4
5
6
7
8
<rich:column>
  <f:facet name="header">
    <h:selectBooleanCheckbox id="t0" value="#{backingBean.selectedAll}" onclick="this.blur()">
        <a4j:support event="onchange" actionListener="#{backingBean.selectAll}" reRender="resultTable, t0, t1"/>
      </h:selectBooleanCheckbox>
    </f:facet>
  <h:selectBooleanCheckbox id="t1" value="#{h.selected}" />
</rich:column>

Make a new method to your backingBean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void selectAll(ActionEvent event) {
	logger.info("*** backingBean.selectAll(): " + scrollerPage + " ***");
 
	// get the current scroller page
	int page = Integer.valueOf(scrollerPage).intValue();
	if (page != 0) {
	    page = page - 1;
	}
	int start = page * 10;
	int stop = (page * 10) + 10;
	if (stop > getResultList().size()) {
	    stop = getResultList().size();
	}
	logger.debug("> page: " + page + "; start: " + start + "; stop: " + stop);
 
	// check the boxes on the active page
	for (int i = start; i < stop; i++) {
	    logger.debug("> valitaan: " + i + "; " + selectedAll);
	    getResultList().get(i).setSelected(selectedAll);
	}
}