Thursday 14 July 2016

Loading Providers and Themes from Maven Repository

Keycloak has a number of SPIs where you can provide your own providers to hook in custom behavior. The custom providers can be deployed by copying the JAR into the providers directory or it can be deployed as a module which provides greater control of the classpath for the provider.

Keycloak also has the ability to create themes to customize login pages and account management console. These can either be copied to the themes directory or they can also be deployed as modules.

In this post I'll show how you can load custom providers and themes from a Maven repository. This could either be from the local Maven repository or a remove Maven repository.

Loading providers and themes from a Maven repository can be useful for development and also as a distribution mechanism, especially when Keycloak is clustered and you want to make sure all nodes have the same providers and themes.

Before going through these examples make sure you have the Keycloak server installed. If you don't you can get it from keycloak.org. We'll refer to the directory where you have the Keycloak server as KEYCLOAK_HOME.

You also need to download the Keycloak examples as we'll use one of the example providers. You can get them from keycloak.org. Then extract the archive somewhere. We'll refer to the directory with the examples as EXAMPLES_HOME.

Deploying Provider as a Module

Before we load the example provider from Maven we'll first deploy it as a module. There's two reasons for this. Firstly, we'll make sure that we have everything configured correctly and that the provider is working as expected. Secondly, loading the provider from Maven is actually a feature of the JBoss Modules which is what provides the support for modules in the first place.

To deploy the provider go through the following steps: Stop the Keycloak server, then build and install the example provider with the following steps:

cd $EXAMPLES_HOME/providers/event-listener-sysout
mvn clean install
$KEYCLOAK_HOME/bin/jboss-cli.sh --command="module add \
 --name=org.keycloak.examples.event-sysout \
 --resources=target/event-listener-sysout-example.jar \
 --dependencies=org.keycloak.keycloak-core,org.keycloak.keycloak-server-spi"
This will create a module for the example provider. Next we need to configure Keycloak to load providers from the. Open $KEYCLOAK_HOME/standalone/configuration/keycloak-server.json in a text editor and update the providers section to:
"providers": [
    "classpath:${jboss.home.dir}/providers/*",
    "module:org.keycloak.examples.event-sysout"
],

Once you've done that start the Keycloak server and login to the Keycloak Admin Console. Select Events from the menu, then click on the Config tab. Remove the jboss-logging listener, add sysout and click on Save. The sysout event listener is the custom event listener provider we just deployed as a module.

To check that the provider is working as expected logout, then login again. You should see some events on the standard output from the Keycloak server:

10:52:01,844 INFO  [stdout] (default task-50) EVENT: type=LOGOUT..
10:52:04,792 INFO  [stdout] (default task-54) EVENT: type=LOGIN..
10:52:04,976 INFO  [stdout] (default task-57) EVENT: type=CODE_TO_TOKEN..

Loading Provider from the Local Maven Repository

Loading the provider from the local Maven Repository is very easy. In the previous steps we already built and installed the provider into the local Maven Repository so we just need to make the module use the Maven artifact instead of the JAR directly from the module.

First stop the Keycloak server. Then delete the file modules/org/keycloak/examples/event-sysout/main/event-listener-sysout-example.jar. Next open $KEYCLOAK_HOME/modules/org/keycloak/examples/event-sysout/main/module.xml in a text editor and change it to:

<?xml version="1.0" ?>

<module xmlns="urn:jboss:module:1.1" name="org.keycloak.examples.event-sysout">

    <resources>
        <artifact name="org.keycloak:event-listener-sysout-example:2.0.0.Final"/>
    </resources>

    <dependencies>
        <module name="org.keycloak.keycloak-core"/>
        <module name="org.keycloak.keycloak-server-spi"/>
    </dependencies>
</module>

Note: if you are not using version 2.0.0.Final of the examples remember to change the version.

You can now start the server again and try login. You'll hopefully see that the events are still being printed to standard out. As you deleted the JAR from the module directory the provider is now being loaded from the local Maven repository.

Loading Provider from a Remote Maven Repository

Let's start by creating a Nexus repository we can use to deploy the provider to. We'll use Docker and the official Sonatype Nexus image. You can obviously use any Maven Repository you want, but for the sake of completeness we'll include steps to setup the repository as well. Make sure you have Docker installed then run: docker run -d -p 8081:8081 sonatype/nexus After a while you'll have a Sonatype Nexus Maven Repository running at http://localhost:8081. You can login to this with username admin and password admin123. Now let's deploy the example provider to this repository. First edit the file .m2/settings.xml in your home directory and add the credentials for the Sonatype Nexus repository:

<settings>
    ...
    <servers>
        <server>
            <id>local-nexus</id>
            <username>admin</username>
            <password>admin123</password>
        </server>
    </servers>
</settings>
Then edit $EXAMPLES_HOME/providers/event-listener-sysout/pom.xml. Add a distributionManagement element:
<distributionManagement>
    <repository>
        <id>local-nexus</id>
        <name>Local Nexus</name>
        <url>http://localhost:8081/content/repositories/releases</url>
    </repository>
</distributionManagement>
Also, you need to enable the deploy plugin as it's been disabled in the parent POM:
<build>
    <finalName>event-listener-sysout-example</finalName>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
            <configuration>
                <skip>false</skip>
            </configuration>
        </plugin>
    </plugins>
</build>

Now you can run the following to deploy the provider to the repository:

mvn deploy

Check that it was indeed deployed by opening http://localhost:8081/content/repositories/releases/org/keycloak/event-listener-sysout-example/.

Stop Keycloak. To make sure the provider can indeed be retrieved from the remote Maven repository delete the directory .m2/repository/org/keycloak/event-listener-sysout-example. This will remove the provider from the local Maven repository. You can try to start the Keycloak server again, but you will get a warning. To enable the remote Maven repository start the Keycloak server with:

bin/standalone.sh \
 -Dremote.maven.repo=http://localhost:8081/content/repositories/releases

Keycloak should now start successfully and should download the provider from the remote Maven repository. It'll get cached in the local Maven repository so it won't have to retrieve it every time Keycloak is started.

Tuesday 5 July 2016

IntelliJ IDEA Review

Everyone is different and everyone has a favorite IDE. On the Keycloak team you'll find someone that uses each of the major IDE's, Eclipse, Netbeans, and IntelliJ. We don't discriminate and let each person decide which they want to use rather than impose one IDE on everyone.

Both Eclipse and Netbeans are available free of charge and are open source, which is obviously ideal. IntelliJ IDEA usually has a license fee, but JetBrains have provided our team with a free-of-charge IntelliJ IDEA license in exchange for displaying a JetBrains logo on our project website and an objective review of the software in a blog post.

In the modern world of Java software development it's nearly impossible to get far enough with notepad and great memory. This programming language and all those popular frameworks have nowadays gone so far that every new Java software developer has to deal with choosing the right instrument which will help him all along on the harsh journey of Java development. He has to choose an IDE.

Today market is not very rich on the variety of Java development environments. The most popular of the existing ones are probably Netbeans, Eclipse (also some of it's derivatives, including Jboss Developer Studio) and IntelliJ IDEA, developed by JetBrains.

It should not be a surprise for the reader, that our team uses all of the mentioned IDEs. Many software developers, being quite a conservative folk, tend to quickly get used to a single instrument and are not willing enough to try the shiny other ones, being quite reasonable on the point that this adventure might just consume all of their precious time and give none positive result in return.

So, this is the reason why this article originally came out, to help anybody interested take a peek at the IDE which is getting more and more popular around our team. I am going to write about IntelliJ IDEA.

Different Bundles


IntelliJ IDEA is distributed in two different bundles - community edition and ultimate edition. It's not difficult to guess that first one is free to use with somewhat limited functionality, but it's license (Apache v2.0) allows it's users to work on commercial projects with this IDE, and even modify and extend IDEA in order to create a new commercial product on top of it.

Ultimate edition is meanwhile not free at all. To be honest it's price is not that low as to be affordable by an average student. There are a lot of different modules out there for ultimate edition which are not compatiable with community edition of IDEA. Among them are modules for Java EE and Spring integration, which, among other features, provide possibility to debug applications running inside application servers, nice injected beans navigation and many others.

At the same time JetBrans has created a vast amount of other products, which are developed on top of IDEA. Most well-known of them all are probably WebStorm (Javascript IDE) and PyCharm (Python IDE). There also exist IDEs for C++, ruby, iOS development and more. Recently JetBrains family received a new member called Datagrip. It is an IDE for RDB stored procedures and SQL development, which supports all the most popular databases. The thing which most distinguishes DataGrip from it's rivals is that DataGrip caches all the database schemas user needs during the first connection to the database, and after that provides reliable and fast autocompletion during the user's interaction with these schemas. Unfortunately, DataGrip does not have anything like community edition, it's a product one will have to buy. It provides 30-days trial period though, in case you would like to get familiar with it and see if you really need it.

It also should be said, that JetBrains provides free ultimate edition licenses for developers involved in opensource products. If you're one of those developers and want to get your ultimate edition license, you probably should get in touch with JetBrains and discuss this topic with them.

Look and feel


When I first started IDEA after a long time working with eclipse (please don't consider this being some sort of advertising, eclipse is a great opensource product!), I was very surprised, how fast IDEA was at doing all those little things developer needs from an IDE. That was the first time I believed that even desktop applications written in Java might be really competitive on the market.

When you first import or create a project in IDEA, it will cache a lot of different things related to it. IDEA will cache all the classes with there properties and methods, all project dependencies, annotations and all the other things needed to run the application. Maven dependencies will also be downloaded and added to project classpath.

Obviously, miracles never happen, so this pro has it's own con. Project import might take a really long time. For example, Keycloak import takes at least two cups of coffee. Fortunately this is not the task one has to do very often.

One more nice thing about IDEA is that this IDE is fully customizable. There are two color schemes out of the box, light theme for daylight Java development, and dark one, for midnight hacking. What is the most important, on the contrary to most other IDEs, which only allow users to change editor color, IDEA has a customizable interface. User can change everything, from window colors to fonts in settings area.







Of course, editor customizing is also available. More than that, user can set different color schema for every language he works with in IDEA. Every keyword type has it's own color setting, and every language has it's own color page in IDEA settings, fonts can be changed, and even font styles can be used for different language elements. For example, user can set class names to be bold and class static methods to be written in italic. This customization can actually save a lot of time while navigating code.


Usually software developer, working with code, prefers to restrain from using mouse and work with keyboard only. Thus, good IDE should provide as many keymaps, as possible, for different kinds of things. IDEA is doing a really great job here. User can choose from keybindings which come from Eclipse, Visual Studio, Netbeans, Emacs and even Vim (full Vim emulation can be installed with IdeaVim plugin). User can also create his or her own keybindings.

Plugins


IDEA supports loads of very different plugins. Some of them extend development environment with new languages, others with version control systems. There are plugins for different class hierarchies and diagrams, plugins for refactoring, there are ones, which provide highlighting for different configuration and markup files.

For example, I really fancy a Markdown support plugin, which provides source highlighting and markdown files preview. User can extend IDEA by adding Gerrit or Github plugins and Scala plugin, which provides Scala autocompletion, syntax highlighting, built-in SBT (Scala Build Tool) and REPL for testing code. Needless to say that in this case IDEA will adopt new run configurations, for Scala specifically, and new VCS menu with actions, usual for Gerrit and Github.

There are also plugins which introduce such languages as Groovy (with Gradle), Kotlin, Clojure (with Leiningen) and many others.


Every willing person can take part in community's life, develop plugins he or other people might need and distribute them to others. It should be mentioned though, that modules, which rely on ultimate edition functionality, will not be available in community edition IDEA. For example, not a single module which works with Java EE, can be installed in the free version of IDEA.

Maven Integration


Nowadays Java is tightly coupled with Maven. One can hardly find a Java project which is not built by maven. Both Spring boot and Java EE use maven dependency management a lot, and it's nearly impossible to develop a modern project without it.

Therefore, it's fortunate that JetBrains have done quite a big job on IDEA Maven integration. Maven is bundled with IDEA out of the box. Though the bundled version is quite old, it's easy to point IDEA towards Maven installation somewhere in the OS, if one needs the more modern one.

On Maven project import IDEA scan it for Maven modules and caches them afterwards. After that it downloads all the artifacts needed by the project to be built and run and puts them into this project's classpath. Both IDEA editions, community and ultimate, have a handy Maven tool, which makes it easier to manage lifecycle of the application. This instrument lists all maven modules available in the project with their goals, and also the full list of Maven profiles available to run those goals with.



It also should be mentioned that IDEA has quite a good autocompletion when dealing with Maven configurations. It can even suggest artifact version in maven repositories on filling dependencies of maven project, which often comes very handy.


IDEA also has nice support of Ant scripts, in case your projects are built with it instead of Maven.

Java EE and Spring Integration


Unfortunately, Java EE and Spring integration is only available to users of ultimate edition of IDEA.

And, while Spring heavily relies on it's maven dependencies, and is able to embed almost everything it needs into the application being developed, which makes Spring applications easily run even in community edition, Java EE is not anywhere that easy to cope with. Of course, user can start application server by hand, deploy Java EE application to it with maven or any other tool and setup debug flags to the application server, it's not easy and comfortable to do this all the time during application development. That's why if one works with Java EE a lot and has growing interest in IntelliJ IDEA, he might think about obtaining an ultimate edition license. This can save a lot of time and effort. Don't forget about the 30-days trial!

Meanwhile, there's nothing very much special about Java EE integration in IDEA. It's presumably the same thing as Java EE in eclipse, JBDS and others. Though, in my opinion, Java EE configuration in IDEA is one of the most comfortable of all the IDEs I've worked with, nobody spends more time configuring their tools than actually developing applications with them.

In IDEA settings user can setup multiple application servers, which have to be preinstalled into the system, with a little bit of configuration involved, usually default settings do the trick. After that user specifies application server in project settings, and that's it. It's now possible to start the AS, deploy application, debug, see logs and do all the other funny things related to application servers, all from the IDE.


Of course, IDEA also provides nice tools for navigation around the enterprise code. It's easy to see all the places bean is injected to, to find all the observers of the CDI event, etc. This works for both Java EE and Spring.

Conclusion


In my opinion, IDEA is one of the best development tools for the vast majority of programming languages on the modern market. It's fully customizable, it provides all the instruments I would ever like to see in the IDE, if not from scratch, then installed as a plugin. It's nice to work with, never lags or freezes, and always quickly responds to my thoughts and wishes. I don't have to wait for and IDE to remember what is in classpath, so I can switch my attention to software development instead of getting mad with instruments.

Meanwhile main disadvantage of IDEA is it's price, especially if you don't work with opensource and your employer refuses to pay for cool shiny toys. In this case it's going to be your decision, whether to spend money on the operating tool or not. Fortunately, community edition exists, and ultimate edition is always available for a 30-days trial period, so you at least have enough time to try it and decide if you really need it.