Bringing Scala into the Java EE Space
Merging Scala and CDI using SBT - Part 2
Running SBT, an Introduction
Running SBT is a straightforward process and is governed by actions. If you are coming from Maven, some of these action names are already very familiar to you. Here is a small sample of actions that you will need for the article.
• reload: Compiles the project definition file.
• compile: Compiles all main source files in your project.
• test-compile: Compiles all test source files in your project.
• update: Downloads all dependencies from repositories into the /lib_managed directory of your project.
• clean-lib: Cleans up the /lib_managed directory. This is useful in case some libraries are still around that you don't want anymore.
Each action can be run from the command prompt of your shell by running the command sbt along with the action you wish to run. For example, running sbt compile at the command prompt will compile your entire project. Running sbt test would compile and test your entire project. Alternatively you can run actions by invoking the SBT environment shell by running the command sbt. Once in the sbt shell, you can run all your actions without typing sbt before each action. This is especially useful for triggered executions which I'll be discussing next.
Triggered executions are like the regular actions we mentioned in the previous section. The difference is when the action is complete it will wait until you make another change to a file. Once SBT notices that a change has been made to a file, it will run your action again until you hit the ENTER key. Triggered execution actions are named the same as the regular actions except they are prepended by a "~". Here is another small sample set of sbt triggered executions that will be useful for this article.
• ~compile – Compile all main source files in your project then wait for a source file to change, after which time the changed files will be compiled again.
• ~test-compile – Compile all test source files in your project then wait for a test source file to change, after which time the changed test files will be compiled again.
• ~test – Run all tests, then wait for a file to change, after which time the file will be compiled and tested again.
• ~test-quick – Run all failed, new, and recompiled tests then wait for a source or test file to change, after which time, the files will be compiled and tested again.
• ~test-failed – Run all failed and new tests then wait for a source or test file to change, after which time, the files will be compiled and tested again.
In Figure 1 we have some files that need to be included in the WEB-INF folder in order for you to use CDI and to use Scala with CDI. First, in order for the war file to become a CDI based war file you need to include a beans.xml file in the webapp/WEBINF folder. The beans.xml file can be used to map components used for dependency injection but for our purposes we will leave an empty shell as shown in Listing 3.
Secondly, I am including a blank faces-config.xml in the webapp/WEB-INF directory so that a Java EE Application server can detect this war file as a Java Server Faces ready war file. Again this file, as seen in Listing 4, will be an empty shell, since we don't have page navigation directions at this time. Next, the file jboss-scanning.xml is a vital file if you are considering using Scala with your Java EE war file in a JBoss Application Server. The jboss-scanning.xml file will specify what classes the Application Server can scan. If this file is not present, JBoss will complain about certain Scala types it was unable to scan and will refuse to load your war file. Listing 5 shows what should be included in jboss-scanning. xml file. Notice that we will be telling JBoss to skip all scala packages in the scala-library.jar file located in WEB-INF/lib/scala-library.jar.
Lastly, the tried and true web.xml file is required. Our targets for this project are modern application server systems like JBoss 6.0.0.Final and Glassfish 3.1 so the setup is fairly small and familiar to the seasoned Java Web Developer. In Listing 6, we declare a session time out, a context parameter that we are in a Development project stage and we declare a FacesServlet to process our Java Server Faces on files that end in .xhtml suffix.
If you are not using a modern application server there is some more initial setup required for this project to work with your web-app 2.5 container. Please visit "Pre-Servlet 3.0 Configuration" Seam-Servlet documentation for additional configuration.
Creating our war file
We are now ready to create our war file. In Listing 7, we run the following commands in a terminal using sbt. As mentioned above in "Running SBT, an Introduction". The reload command will recompile our CDIScalaProject. scala build file for use. If there is an error, you can recompile by running sbt reload again. The update command will download our dependencies. Running sbt clean and package will create our war file.
Once completed locate your war file in the target/scala_2.8.1 directory. Typically the war file will be the name of the folder your project is in followed by the scala version it was built with and then the version number of your project. For example, a project folder called cdi-scala, my war file is called cdi-scala_2.8.1-1.0.war.
Your file is now ready to be deployed to either JBoss 6.0.0.Final, Glassfish 3.1, or your Java EE 6 compliant application server of choice.
Upgrading Weld in Glassfish 3.1
Weld is the CDI Reference Implementation of JSR-299, Java Contexts and Dependency Injection for the Java EE platform. It is the core Dependency Injection framework used in both JBoss 6.0.0.Final and Glassfish 3.1. Currently the Weld implementation in Glassfish 3.1 needs to be upgraded in order for your war file to work as expected. This is the nature of bleeding edge technologies and case studies. Therefore, please visit the Seam and Glassfish integration guide at seamframework.org to get a workaround on this issue and any other issues that may arise.
This is merely the first step for my case study. I will be exploring and testing how far I can go with Scala and CDI and determine its boiling point. This project is freely available on GitHub and has everything contained in this article, including code that I will be using to pressure test the Scala language with CDI/Seam3.
For more information on the 'Functional Programming in Scala with CDI' session, check out the JAXConf website! Early Bird registration ends TODAY – register now, and save up to $200.
- What is SBT?
- Running SBT, an Introduction