Scalaz monads in Spring

I won’t give you the category-theory based explanation of monads. Instead, I’m going to show you the application of monads, but not on Ints and Strings, but on ordinary domain instances; instances that we persist using Hibernate. Finally, we’ll run the entire example in the Spring Framework.

Why the complexity, you ask? My team often found the simple examples understandable, but they struggled to see the application of the monads to day-to-day business code. “Sure, we write monads that read a String from a file, chain it to monad that converts the String to Int, but we’re having to generate reports,” they said.

The service

Let’s write a ReportService that generates reports and then produces a combined report by combining the individual reports into one. Its API is:

class ReportService {

  def produce()

  def combine()

}

Where the produce function generates the individual reports (pages, if you like); and the combine function takes the already generated reports and assembles the aggregate. We keep these reports in the database (and the content on the disk) and we map the RDBMS records to the Record instances. We are using Hibernate, leading the definition of the Report class:

@Entity
case class Report() {
  @Id
  @GeneratedValue
  @BeanProperty
  var id: Long = _
  @Version
  @BeanProperty
  var version: Int = _
  @BeanProperty
  var fileName: String = _

}

As I said earlier, we are using Hibernate to manipulate the Record instances, so our ReportService will need to depend on the SessionFactory. Because we’re running in the Spring Framework, we can have the dependency injected in. We just have to give the appropriate metadata to the Spring Framework’s DI core:

@Service
class ReportService @Autowired() (private val sessionFactory: SessionFactory) {

  def produce()

  def combine()

}

We’ll start with the produce() function. The task is to generate [a fixed number of] reports. So, we’ll need a for loop whose every iteration creates a Report instance and saves it to the DB.

@Service
class ReportService @Autowired() (private val sessionFactory: SessionFactory) {

  @Transactional
  def produce() {
    for (i < - 0 to 100) {
      val report = Report()
      val content = "Report %d".format(i)
      report.fileName = "%d".format(i)

      // save the report's content

      sessionFactory.getCurrentSession.saveOrUpdate(report)
    }
  }

}

So far, so good. We have the fancy Scala for loop, but the code remains very similar to its Java equivalent. Now, let's deal with the IO. To save a report, we need to:

  • create / open a file into which the content is going to go,
  • produce the report's content,
  • write the content to the file.

    So, we have three operations. We go from Report to operation giving File, second that goes from operation giving File and operation giving Data to operation giving Unit. So, let's write these operations and define what we mean by Data:

    @Service
    class ReportService @Autowired() (private val sessionFactory: SessionFactory) {
      type Data = Array[Char]
      import scalaz._
      import scalaz.effects._
    
      def reportToFile(report: Report) = io {
        new File("/Users/janmachacek/Tmp/r/%s".format(report.fileName))
      }
      def dataToFile(data: IO[Data])(file: File) = io {
        println("Written " + new String(data.unsafePerformIO) + " to " + file)
      }
    
      ...
    
    }
    

    The function reportToFile is the one that takes a Report and returns an operation that gives File. The operation that gives is whatever the io function returns. Then I have the dataToFile function that takes an operation that takes operation that gives Data and returns an operation that gives Unit. Figure 1 shows a picture of what we're trying to do.

    Figure 1. The operations and the links between them

    We would like to wire the three operations together to give us a new operation that combines the three together!

    This is crucial concept: we're not just pushing data around, we're creating a new operation that combines the smaller operations to do something useful for us. So, let's drop in the real syntax:

    @Service
    class ReportService @Autowired() (private val sessionFactory: SessionFactory) {
      type Data = Array[Char]
      import scalaz._
      import scalaz.effects._
    
      def reportToFile(report: Report) = io {
        new File("/Users/janmachacek/Tmp/r/%s".format(report.fileName))
      }
      def dataToFile(data: IO[Data])(file: File) = io {
        println("Written " + new String(data.unsafePerformIO) + " to " + file)
      }
    
      @Transactional
      def produce() {
        for (i <- 0 to 100) {
          val report = Report()
          val content = "Report %d".format(i)
          report.fileName = "%d".format(i)
    
          (reportToFile(report) >>=
             dataToFile(io {content.toCharArray})).unsafePerformIO
    
          sessionFactory.getCurrentSession.saveOrUpdate(report)
        }
      }
    
    }
    

    Let's explore the mystical (reportToFile(report) >>= dataToFile(io {content.toCharArray})).unsafePerformIO line. We have reportToFile takes a Report and makes a thing that makes a File. Then we have dataToFile which takes a thing that makes Data and thing that makes File. We treat these things as black boxes--they do something obscure, unknown and unknowable. But these things have a "screen" on them; and we can look at that "screen" and obtain the current value.

    And that's the principle of monads. They are opaque things that can return some value and they can be chained together to form new things that combine whatever the component things do.

    And that explains the unsafePerformIO call. The (reportToFile(report) >>= dataToFile(io {content.toCharArray})) simply returns a new monad, but we must "look at its screen"; make it compute a value, in other words. And that's what the unsafePerformIO function does.

Onwards, then! Let’s implement the combine function that selects all existing reports, and merges them into a one fat report that it then saves.

@Service
class ReportService @Autowired() (private val sessionFactory: SessionFactory) {
  type Data = Array[Char]
  import scalaz._
  import scalaz.effects._
  import scala.collection.JavaConversions._

  def reportToFile(report: Report) = io {
    new File("/Users/janmachacek/Tmp/r/%s".format(report.fileName))
  }
  def dataToFile(data: IO[Data])(file: File) = io {
    println("Written " + new String(data.unsafePerformIO) + " to " + file)
  }
  def fileToData(file: File) = io {
    Source.fromFile(file).toArray
  }

  @Transactional
  def produce() {
    ...
  }

  @Transactional
  def combine() {
    val reports =
      sessionFactory.getCurrentSession.createCriteria(classOf[Report]).
        list().asInstanceOf[java.util.List[Report]].toList

    val out = Report()
    out.fileName = "out.txt"

    // take the reports and make one big fat report out

    sessionFactory.getCurrentSession.saveOrUpdate(out)
  }

}

The combine selects all Report records, and (using the function in scala.collection.JavaConversions._) converts the java.util.List[Report] into scala.collections.immutable.List[Report]. How do we now combine the reports? Let’s think about it:

  • If the reports contains just one item, then the result is that one item,
  • If the reports contains two items, then we need some function that takes two Reports and makes the combined Report,
  • If the reports contains many (i.e. more than two!) items, then we take the first two and combine them into one (using the function from the previous step). Then we take the combined report and combine it with the third item; then we take the combined report and combine it with the fourth item; and so on, until the end.

    So, we need a function that combines two reports into one and then an operation that implements the algorithm we described earlier. The name for the operation is foldl1 and Figure 2 shows how it works:

    Figure 2. foldl1 function

    The arrows in the image are our function and report1, report2, ..., reportn is our list. Hence the code of the combine function becomes:

    @Service
    class ReportService @Autowired() (private val sessionFactory: SessionFactory) {
    
      ...
    
      @Transactional
      def combine() {
        val reports =
          sessionFactory.getCurrentSession.createCriteria(classOf[Report]).
            list().asInstanceOf[java.util.List[Report]].toList
    
        val out = Report()
        out.fileName = "out.txt"
    
        reports.foldl1 { (r1: Report, r2: Report) =>
          // read the r1 and r2 from the files,
          // combine them and write to out
          out
        }
    
        sessionFactory.getCurrentSession.saveOrUpdate(out)
      }
    }
    

    We now have to read the report from a file into Data and the combine the two Datas representing the reports together. The good news is that we have already written the monads that deal with the report IO. All we have to do is to combine them to form new interesting monad that combines the reports.

    @Service
    class ReportService @Autowired() (private val sessionFactory: SessionFactory) {
    
      ...
    
      @Transactional
      def combine() {
        val reports =
          sessionFactory.getCurrentSession.createCriteria(classOf[Report]).
            list().asInstanceOf[java.util.List[Report]].toList
    
        val out = Report()
        out.fileName = "out.txt"
    
        def combine(data: (Data, Data)) = io { data._1 ++ data._2 }
    
        reports.foldl1 { (r1: Report, r2: Report) =>
          (reportToFile(out) >>= dataToFile(
            (reportToFile(r1) >>= fileToData) <|*|>
            (reportToFile(r2) >>= fileToData) >>= combine)
          ).unsafePerformIO
    
          out
        }
    
        sessionFactory.getCurrentSession.saveOrUpdate(out)
      }
    }
    

    You already know about chaining the monads (using >>=), the new thing in the reports.foldl1 function is the <|*|> operation. Think of this operation indeed as multiplication, but multiplication of the computed values of the monads. The monad on the left-hand side ((reportToFile(r1) >>= fileToData)) computes Data, the monad on the right-hand side ((reportToFile(r2) >>= fileToData)) computes Data. In this case, we have Data * Data, in other words a pair–tuple in computer speak–of Data. And that’s precisely what the combine function takes (its body simply appends the two arrays) and it returns the combined IO of Data… and we can use it as input of the dataToFile function, which is an IO monad that follows the reportToFile(out) monads.

    The whole contraption represents our report + report function; which we give to the foldl1 function. For completeness, we save the combined report using the injected sessionFactory.

    Summary

    This code combines dependency injection, load-time weaving (courtesy of the Spring Framework) with elegance and effectiveness of the Scala code. Finally, we take advantage of the IO monads in Scalaz to compose the individual trivial operations (report -> file, data -> file, etc.) to compose new operations that we use in the produce and combine functions.

Posted in Jan's Blog | Tagged , , , | Leave a comment

This week in #Scala (03/02/2012)

Welcome to another week in #Scala. We’ve been busy working on our open source projects here at Cake and have finally got spec2 spring published to Maven central and Sonatype. This week has been fairly quiet from a Scala point of view (compared to normal standards anyway) but there are still a few interesting posts and releases to tell you about.

 

New Stuff

Scalaxb 0.6.8 is now available! scalaxb is an XML data-binding tool for Scala that supports W3C XML Schema (xsd) as the input file.

Specs2 Spring version 0.4. In addition to many minor changes and bug fixes this release improves support for spring 2.5, adds hibernate 4 support and allows the @Bean annotation to be used from within Scala code. Find out more about spec2 spring and our other open source projects in Jans blog.

Have a look at Styla – A fairly complete and fast Prolog interpreter written in Scala, using Paul Tarau’s Java-based Kernel Prolog as starting point.

Less-sbt 0.1.5 is now available. This release fixes a few issues and now uses the less-rhino-1.1.5.js compiler. Click through for more details.

 

Blogs and tutorials


As usual feel free to drop me a mail or message @markglh on twitter with any Scala news!

Posted in Mark's Blog | Tagged , , , , , , | Leave a comment

Why we come to work at Cake

One of the most noticeable attributes of everyone at Cake is the burning desire to acquire, assimilate and utilise as much knowledge about what we do for a living as we can – it’s an addiction in good sense.

This came up as we were closing-out a recent stand-up meeting on an agile project, when the team were excited about some of the functional programming ideas we’d come up with. I love this place…my knowledge increases every day said one of the team, and this got me thinking about why Cake is such a great place to work – we live and learn and do great stuff – and we get paid for it too!

Cake is about to embark on a period of growth, with the opening of our second office, in Oxford. It’s a clear statement of ambition and confidence, and at the same time it’s a big stretch. We need to ensure the Cakeness which makes us special is preserved, especially the knowledge pool. Working for a small company means we have an intimacy about the team, especially individual and collective knowledge, rapport and camaraderie – it’s not like working for a large company, which is like getting on a train with all the other passengers. Are you doing fifty miles and hour or is the train going fifty miles an hour and you’re just standing still?

We’re knowledge and innovation business, operating in the software development market, and consequently everyone wants to make a difference and keep on top of their game. So what drives us in this hunger for knowledge?

You start craving for knowledge and do not leave any source unturned to acquire it. It may be making you and people around you wiser, it could be adding spiritual maturity to you or it could be to improve your capability and fulfilment in your current or future role at work. Whatever your motivation, the mental process of knowing, including aspects such as awareness, perception, reasoning, and judgment are all stimulating and interesting points for self-reflection.

What is it that drives people into the jungles of the unknown? For me it is the mind’s inner urge to seek more learning, developing points of view and perspectives. The all-absorbing urge for knowledge is one of the thinking person’s deepest needs, and for me knowledge is interesting in itself and is personal strength, the greatest strength of all. There is much effort in gaining knowledge by everyone of us as we all think that what knowledge we have is insufficient. By understanding ever more knowledge, testing it and experiencing the wisdom in it one can only ever love the thirst. It is knowledge that is truly satisfying to our spirit, it brings us life and ever more greater life. Of course, that depends on your point of view, I’ve heard some people say ‘Ignorance is paradise’, but for me that’s simply not true.

But is the widespread availability of technology generating such wisdom or even improving our learning? Research shows that students using Google and online information portals today are producing work no better than they were 20 years ago using printed sources. Despite amazing technical breakthroughs, these technologies haven’t added to human knowledge, rather making plagiarism rife and discouraging original thinking and ‘lazy’ research. Information on a plate to satisfy short-term hunger, rather than feeding a yearning for genuine knowledge, and while technology enthusiasts celebrate the destruction of old industries, we’re left with the banality of Google and Wikipedia.

Of course, e-books are great inventions of convenience, but just like iTunes and digital music downloads, the tactile experience of holding a book in your hands is lost just as the loss of album sleeve notes is no longer part of the experience. However, I realise that after spending my Christmas Amazon vouchers – on a combination of ‘real’ books and kindle e-books – that I’m a collector of books rather than a reader, but feel good about myself in that I have an accumulated stock of future reading and thus a pile of new knowledge to unearth from reading.

Once I’ve done this, I find the tactile experience of finishing a physical book and closing it for the last time produces a mellowness, a warm glow, an inner feeling of contentment and happiness. Ok, we have the web with various blogs and online community sources to reach out and get new knowledge, but there is something about reading a book, the physicality of having it in your hands, that stands out from digital media.

The most wonderful thing that reading offers is a peep into another world. When you pick up a book and lose yourself into it, its like you have transcended your present situation. This temporary escape from our routine life is of great significance when it comes to your mental well-being. We all have day-to-days tasks to take care of, and many a times we go to bed all tense and frustrated and sometimes just downright bored with life. This is when reading comes to our rescue and we should welcome it with open arms if we truly want to be happy and alive. Reading offers us a chance to see the world from someone else’s eyes, thus broadening our horizons and opening our minds to new possibilities. Reading is to the mind what exercise is to the body.

You emerge out of this trance-like situation, fully refreshed, with a clearer vision and rejuvenated spirit. So the next time you feel as if your mental batteries could do with a recharge, pick up a good book and immerse yourself into for a good hour or so. And mind you, this solution comes with a guarantee card.  Reading is a great imagination booster and it helps develop a sense of creativity in you. It will also help you develop better concentration which we need so bad at all times.

Are there many times in life where you probably find yourself gaining knowledge and coming to a place where everything is working well for you at the given moment because of your newfound awareness……but then it all fall apart again at the next moment?

Sometimes it just makes you wonder what the heck is going on. The reason is because you still haven’t possessed the rest of the awareness you need for it to happen. As you keep learning and growing, you will keep getting more and more pieces of the puzzle so that you are able to acquire better and better mastery in different areas of life for creating your desired reality. Your life will get better and better when you keep picking yourself up in those areas that you have fallen and walk on, and do some great stuff!

But back to Cake, and our knowledge pool, and the point about knowledge, fulfilment and personal progression at work. Think about the formula for the traditional deal at work, which goes something like this:

I work… to earn money… which I use… to consume stuff… which makes me happy.

I suggest that this deal is not a sufficient description of what work can and should be. Instead I put forward the following knowledge-based and future-focused deal, which we think makes Cake different:

I work… to gain productive experiences… to improve my knowledge…that is the basis… of my happiness.

But this begs the question – what exactly is a meaningful productive experience, and how do you know when your work is meaningful? So here are the 10 questions we asked ourselves to establish whether our work at Cake is meaningful, based around knowledge, fulfilment and all the stuff we’ve gone on about above:

  • Do you use the majority of the knowledge you have on a daily basis?…because meaningful work provides an opportunity for you to keep your knowledge fresh by using it constantly.
  • Do you feel intellectually stretched in your work?…because meaningful work both uses the knowledge you have and pushes the boundaries of what you can become.
  • Are you able to learn something new at least once a week?…because meaningful work creates constant opportunity for learning.
  • In your view are your colleagues at work knowledgeable and do you learn from them constantly?…because meaningful work is also about the colleagues who come with it, and your learning and development comes primarily through learning from others: ‘The Cake Tribe’.
  • Are the tasks you do at work interesting and complex?…because at the heart of meaningful work are the day-to-day tasks that you do.

 

  • Do you get lots of feedback about how you are doing?…because meaningful work enables you to grow, and feedback from others is a crucial part of this.
  • Do you think that the work you do has a positive impact on the business?…because meaningful work enables you to make a clear link in your mind between the tasks you perform and the broader goals of the business.
  • Do you think that the work you do has a positive impact on society?…because meaningful work is made up of tasks that you believe do good and, as a consequence, make you feel good about yourself.
  • In your daily work, do you have the opportunity to reach out to develop networks with people very different from yourself?…because meaningful work creates opportunities for you to develop the ‘Big Ideas Crowd’ that is so crucial to developing your innovative and creative capacity.
  • Does your work give you time to really develop deep regenerative relationships with people inside and outside of your organisation?…because meaningful work creates time and space for you to develop emotionally.

 

So where are you on meaningful work?

Score 8-10 Through your active choices, or sheer luck, you are working in a meaningful way. Cherish the opportunities this provides and don’t compromise in the future.

Score 5-7
Some aspects of your work are meaningful. Take a closer look at those you have said no to and search for the underlying patterns. Is it possible to focus on developing these areas?

Score 1-4
Your job lacks meaning – you already know that! The question is – what are you going to do about it?

So there you have it, an inside perspective of what we think about in Cake when we’re not building great software. Take a look at our blogs, get in touch and join one of our communities, come inside for a conversation where we can share knowledge and do some meaningful work together.

 

 

Posted in Ian's Blog | Tagged , | Leave a comment

Specs2 Spring 0.4

We’re pleased to release version 0.4 of Specs2 Spring!

0.4 follows the very short-lived Maven Central practice-release 0.3. We now include support for Spring 2.5, 3.0 and 3.1; for the latest verion of Spring, we include bean profiles and environment variables settable from the test annotations. We have also included support for raw SessionFactory and HibernateTemplate to work with the most popular ORM tool. The updates include:

  • Supports Spring 2.5 through 3.1, including environment values and bean profiles in 3.1,
  • Test data setup (using BeanTables) now works with HibernateTemplate as well as SessionFactory in Hibernate 4
  • The @Bean annotation’s type value is now clazz to make it usable from Scala code

Most excitingly, Specs2 Spring is now available in Maven Central and Sonatype OSS! All you need to do now is to include the dependency in your pom.xml:

<dependency>
    <groupId>org.specs2</groupId>
    <artifactId>spring_2.9.1</artifactId>
    <version>0.4</version>
</dependency>

To get started, download the ScalaDocs and PDF user guide; check out the http://www.cakesolutions.org/specs2-spring.html

Posted in Jan's Blog | Tagged , , , , | Leave a comment

Publishing SBT projects to Nexus

Specs2 Spring is available on Sonatype OSS and Maven Central! But how did we get there and what should you do to get the hosting, synchronisation to Maven Central and how do you automate the deployment process? Let’s tackle one thing at a time:

Sonatype OSS support

The first thing to is to open an issue in Sonatype’s JIRA, asking them to set up the Nexus repository for you. Once that’s done, you will be able to publish your snapshots and releases to Sonatype; the releases are then synchronised to Maven Central. The first few pages of Sonatype OSS Maven Repository Usage Guide will show you how to get started.

Building and publishing

Now, this is the interesting bit. We are using SBT to build the project and we’d like to be able to run sbt publish to compile, package and publish the project to Sonatype automatically. Before we can do that, we need to configure GPG and SBT plugin that uses GPG to sign the artefacts. The plugin is xsbt-gpg-plugin, which will use GPG to sign the artefacts–properly signed artefacts are the requirement for Maven Central synchronisation. So, with the plugin, your project/plugins.sbt file should contain:

...
resolvers += Resolver.url("scalasbt", /* no new line */
  new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases")) /* no new line */
  (Resolver.ivyStylePatterns)

addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.5")
...

If you do not have GPG, you must also install & configure it for your platform; if you do not have your keys, you must also generate key pair and then publish your public key. I cannot quite show you how to do this on Windows (sorry, get a Mac!). On OS X, you can use GPG Tools. Download and install it; the first thing GPG Tools will prompt you to do is to generate your key, protected by a passphrase. (I recommend that you keep the passphrase very long, as XKCD points out in Figure 1!)

Figure 1. Key strengths

Before I can release the artefacts in Sonatype OSS releases and in Maven Central, I need to publish my public keys (so that others can verify that the artefacts are intact and that it was I who has produced them). To do that, you can use the GPG Keychain Access (see Figure 2) tool or use the gpg command-line program.

Figure 2. GPG Keychain Access

We are programmers, so let’s turn to the command line: we need to export a key, but to do that, we need to know its identifier:

$ gpg --list-secret-keys
/Users/janmachacek/.gnupg/secring.gpg
-------------------------------------
sec   2048R/90A468A9 2012-01-30 [expires: 2016-01-30]
uid                  Jan Machacek <jan.machacek@gmail.com>
ssb   2048R/A9ED23D0 2012-01-30

$ gpg --send-keys 90A468A9

Your public key is now uploaded to the default key server (specified in ~/.gnupg/gpg.conf) and it will be distributed to other key servers over the next few minutes. Once that happens, you’ll be ready to release your artefacts to Maven Central.

Releasing

Before we’ll configure the JAR signing, we must deal with the publish process. We set the publishTo (and several other settings) in build.sbt to use the Sonatype repository like so:


publishTo <<= version { v: String =>
  val nexus = "https://oss.sonatype.org/"
  if (v.trim.endsWith("SNAPSHOT"))
    Some("snapshots" at nexus + "content/repositories/snapshots")
  else
    Some("releases" at nexus + "service/local/staging/deploy/maven2")
}

Before we can publish our SBT-based project, we must ensure that its generated Maven POMs match the strict requirements of Sonatype and Maven Central. So, we must include the following code in your build.sbt:

publishMavenStyle := true

publishArtifact in Test := false

pomIncludeRepository := { x => false }

pomExtra := (
  <url>http://www.cakesolutions.org/specs2-spring.html</url>
  <licenses>
    <license>
      <name>BSD-style</name>
      <url>http://www.opensource.org/licenses/bsd-license.php</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <scm>
    <url>git@github.com:janm399/specs2-spring.git</url>
    <connection>scm:git:git@github.com:janm399/specs2-spring.git</connection>
  </scm>
  <developers>
    <developer>
      <id>janmachacek</id>
      <name>Jan Machacek</name>
      <url>http://cakesolutions.org</url>
    </developer>
  </developers>
)

Now, before we even attempt to run sbt publish, we need to specify the credentials for the Sonatype repository. But we don’t want to do that in the files we push to the VCS! Instead, we’ll create file ~/.sbt/sonatype.sbt, which sets the credentials setting to the Sonatype ones:

credentials += Credentials("Sonatype Nexus Repository Manager",
                           "oss.sonatype.org",
                           "your-sonatype-username",
                           "your-sonatype-password")

The work is done! We’ve modified

  • ~/.sbt/sonatype.sbt with the Sonatype OSS credentials
  • project/plugins.sbt with the xsbt-gpg-plugin plugin to sign the artefacts
  • build.sbt to include the release settings

Now we can run sbt publish, supply our key phrase go GPG and push the artefacts to Sonatype. If you are publishing snapshot release, then your work is done. If you are publishing a “real” release, keep reading.

Promoting

Once you’ve published your non-snapshot release, you will need to go to the Sonatype Nexus, login, select the staging repository and close it. (Again, follow the Sonatype Nexus guide for details.) Closing will verify that the Maven POMs are well formed, that the artefacts’ signatures are valid. If all is well, your repository will end up in Maven Central within a few hours’ time!

Summary

Publishing SBT-based projects to Sonatype and then Maven Central is easy–once you’ve dealt with the details of the Maven POMs. For complete views of the build.sbt and project/plugins.sbt files, take a look at Specs2 Spring’s sources at https://www.github.com/janm399/specs2-spring.

Josh Suereth (http://jsuereth.com/), the maintainer of the xsbt-gpg-plugin SBT plugin maintains a page where he outlines the latest details of the SBT deployment process. Clicky-here to see Josh’s instructions.

Posted in Jan's Blog | Tagged , , , | 4 Comments

This week in #Scala (27/01/2012)

Welcome to another week in #Scala – it seems everyones been pretty busy this week! We’ve got new releases for Scalaz, Akka and shapeless to name a few, read on…

 

New Stuff

Scalaz 6.0.4 is now available! This latest release fixes a few bugs, including a critical bug in scalaz.concurrent.Actor, and adds some new features.

sbt-idea 1.0.0. This SBT plugin automates creation of IntelliJ IDEA project files from sbt project definitions.

shapeless 1.1.0. Shapeless is an exploration of type class and dependent type based generic programming in Scala.

scalatra 2.0.3 is out. Scalatra is a tiny, Sinatra-like web framework for Scala.

Akka-1.3-RC7. This maintenance release includes several minor improvements and bug fixes.

Akka 2.0 pre-release Milestone 3. The final release is getting closer all the time! This milestone fixes plenty of bugs, improves documentation and adds several new features. Click through for more information.

loglady 1.0.0. loglady is a crazy simple logging API for Scala, wrapping slf4j.

sbt-assembly has been updated to 0.7.3. sbt-assembly is a plug-in for SBT that creates a single jar of your project including all of its dependencies.

The Akka 2.x roadmap has been updated.

groll, a plugin for sbt to view and navigate through the Git history has been updated to 1.2.0

bytecask 0.1.1 is now available. bytecask is a low latency key/value database inspired by Bitcask

Lift Shiro 0.0.5. This is an integration between Apache Shiro and the Lift Web framework.

sbt-native-packager 0.2.0 has been released! Click through for the full details

 

Blogs and tutorials

 

As usual feel free to drop me a mail or message @markglh on twitter with any Scala news!

 

Posted in Mark's Blog | Tagged , , , , , , , | Leave a comment

Specs2 Spring from sources

Specs2 Spring is going into Maven Central as soon as possible (I’ve submitted a request at https://issues.sonatype.org/browse/OSSRH-2760), which means that all you’ll have to do to use it in your projects is to add:

<dependency>
  <groupId>org.specs2</groupId>
  <artifactId>spring_${scala.version}</artifactId>
  <version>0.3</version>
  <scope>test</scope>
</dependency>

Where scala.version property is 2.9.1; or, if you prefer SBT, simply add to libraryDependencies:

libraryDependencies ++= Seq(
  "org.specs2" %% "spring" % "0.3"
)

What to do in the next few days/weeks

But before that happens, you’ll need to build Specs2 Spring yourself. The good news is that it’s not at all difficult. You’ll need:

  1. Paul Phillips’s SBT Extras at https://github.com/paulp/sbt-extras
  2. Clones of https://github.com/janm399/sbt-docbook-plugin and https://github.com/janm399/specs2-spring

Once you download the SBT Extras shell script, put it somewhere you remember and add it to your PATH. In my case, I copied the SBT Extras sbt script to /usr/share/scala/sbt and I’ve modified /etc/profile to say:

export PATH=$PATH:/usr/share/scala/sbt

Next, clone the two repositories to some directory, say ~/sandbox. Then you need to publish both projects to your local Ivy repository (this is where they are going to be picked up from later on).

~/sandbox$ cd sbt-docbook-plugin
~/sandbox/sbt-docbook-plugin$ sbt publish-local
~/sandbox/sbt-docbook-plugin$ cd ../specs2-spring
~/sandbox/specs2-spring$ sbt publish-local

And you’re ready to go. The "de.undercouch" % "sbt-docbook-plugin" % "0.2-SNAPSHOT" "org.specs2" % "spring" % "0.3" are now available in your local Ivy repository; and you can use them in your Maven or SBT projects.

If you would like to contribute, and if you use IntelliJ IDEA, you can generate the IntelliJ IDEA project files by running sbt gen-idea in both projects.

Posted in Jan's Blog | Tagged , | Leave a comment

Mixin composition using reflection

I wanted to be able to construct Scala beans in my Spring application context, but I also wanted to be able to specify the mixins to be included in the constructed bean:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:scala="http://www.springframework.org/schema/scala"
  xsi:schemaLocation=...>

  <scala:bean class="org.cakesolutions.scala.services.UserService" >
    <scala:with trait="org.cakesolutions.scala.services.Mixin1" />
    <scala:with trait="org.cakesolutions.scala.services.Mixin2" />

    <scala:property name="dependency" value="Injected" />
  <scala:bean>

</beans>

The difficulty is that Class.forName function does not allow me to specify the mixins. In the end, I modified a very hacky solution on Stack Overflow (which did not quite work in Scala 2.9 and only used one mixin). The solution involves generating classes that are similar to the classes that the Scala compiler generates when we run something like new Cat with Eating with Speaking. So, here it is in its full gory:

class ScalaBeanFactory(private val beanType: Class[_ <: AnyRef],
                       private val mixinTypes: Seq[Class[_ <: AnyRef]]) {
  val loader = new DynamicClassLoader
  val clazz = loader.buildClass(beanType, mixinTypes)

   def getTypedObject[T] = getObject.asInstanceOf[T]

   def getObject = {
     clazz.newInstance()
   }

   def getObjectType = null

   def isSingleton = true

}

object DynamicClassLoader {
  private var id = 0
  def uniqueId = synchronized {  id += 1; "Klass" + id.toString }
}

class DynamicClassLoader extends java.lang.ClassLoader(getClass.getClassLoader) {

  def buildClass(t: Class[_ <: AnyRef], vs: Seq[Class[_ <: AnyRef]]) = {
    val id = DynamicClassLoader.uniqueId

    val classDef = new StringBuilder

    classDef.append("class ").append(id)
    classDef.append(" extends ").append(t.getCanonicalName)
    vs.foreach(c => classDef.append(" with %s".format(c.getCanonicalName)))

    val settings = new Settings(null)
    settings.usejavacp.value = true
    val interpreter = new IMain(settings)

    interpreter.compileString(classDef.toString())

    val r = interpreter.classLoader.getResourceAsStream(id)
    val o = new ByteArrayOutputStream
    val b = new Array[Byte](16384)
    Stream.continually(r.read(b)).takeWhile(_ > 0).foreach(o.write(b, 0, _))
    val bytes = o.toByteArray

    defineClass(id, bytes, 0, bytes.length)
  }

}

The code cannot yet deal with constructors with parameters and does not copy annotations from the parent class’s constructor (should it do that?). However, it gives us a good starting point that is usable in the scala Spring namespace. Of course, don’t just take my word for it, verify it in a Specs2 specification:

class ScalaBeanFactorySpec extends Specification {

  "getTypedObject mixes-in the specified traits" in {
    val f1 = new ScalaBeanFactory(classOf[Cat],
                                  Seq(classOf[Speaking], classOf[Eating]))

    val c1 = f1.getTypedObject[Cat with Eating with Speaking]

    c1.isInstanceOf[Cat with Eating with Speaking] must_==(true)

    /*
    c1.speak    // in trait Speaking
    c1.eat      // in trait Eating
    c1.meow     // in class Cat
    */
  }

}
Posted in Jan's Blog | Tagged , , , | Leave a comment

SBT – DocBook Plugin

Hey there! I’ve recently just started working with Cake Solutions, Scala and SBT. One of my first tasks was to improve the documentation in Specs2 Spring.

SBT and DocBook

As part of our Specs2 Spring project, we wanted to ensure users had access to Spec2 Spring’s documentation in a format they know and love, we figured we’d use DocBook, the multiformat-generating, markup language.

Fortunately a SBT plugin currently exists for DocBook, however it currently doesn’t have a few features we need.

We have forked the SBT DocBook plugin, because we needed to add support for XInclude, syntax highlighting, ePUB and many other improvements. Find it here.

The Setup

Using it is pretty straight-forward. You should have a directory structure similar to this:

MyProject
  build.sbt
  src/
    main/
      java/
      scala/
      docbook/
        main.xml
        chapter1.xml
        ...
  project/
    plugins.sbt

Simply ensure all DocBook files are in the src/main/docbook directory. Note that if you have multiple DocBook files, the main file must be named main.xml. On the other hand, if there is just one file, feel free to name it anything you like.

Include the plugin in your project/plugins.sbt file as follows:

resolvers += ScalaToolsSnapshots

addSbtPlugin("de.undercouch" % "sbt-docbook-plugin" % "0.2-SNAPSHOT")

That’s it!

Run it!

Generating documents in the format of your choice is pretty easy:


$ sbt html


$ sbt pdf


$ sbt xhtml


$ sbt manpage


$ sbt eclipse-help

Checkout the readme for more options.

How have we done it?

Robust documentation is key to getting the community interested and involved in any project and modular documentation is key to the sanity of the project developers. An easy way to produce modular documentation is by using XInclude, sadly the plugin it uses, Saxon 6.5.3, for processing XSLT, cannot handle XInclude.

After extensive googling & hacking, I eventually turned to Xerces2 to resolve XInclude. The code looks a little something like this:

   private def transformDocBook(src: File, dst: File, styleSheet: String,
  cp: Classpath, log: Logger) {
    transform(src, dst, log) {
      //write output to temporary file. this avoids a bug in Saxon
      //that caused spaces in the output filename to be converted to
      //an escaped sequence (%20)
      val temp = File.createTempFile("sbt-docbook-plugin-", ".fo")
      val code = Fork.java(None, Seq[String](
      "-cp", cp.files.mkString(File.pathSeparator),
      "-Djavax.xml.parsers.DocumentBuilderFactory="+
        "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl",
      "-Djavax.xml.parsers.SAXParserFactory=" +
        "org.apache.xerces.jaxp.SAXParserFactoryImpl",
      "-Dorg.apache.xerces.xni.parser.XMLParserConfiguration=" +
        "org.apache.xerces.parsers.XIncludeParserConfiguration",
      "com.icl.saxon.StyleSheet",
      "-o", temp.toString,
        src.toString, styleSheet
      ), log)

      //copy temporary file to real output file
      temp #> dst !

      //delete temporary file (if this files it will be deleted on exit)
      if (!temp.delete()) {
        temp.deleteOnExit()
      }
      code
    }
  }

So what’s going on here? Well Fork.java makes it possible for us to run a separate java process, "-cp" sets up it’s classpath, cp.files.mkString(File.pathSeparator) ensures that the correct path separator is used for your file system, the first 2 -D options set Xerces as Saxon’s xml parser, the last -D option turns on the XInclude feature and -o set’s Saxon’s output file or directory!

Maintaining Specs2 Spring and any other documentation has been made a little easier!

The next focus will be on improving the plugin’s output for documentation split into multiple files, in particular EPUB..

Posted in Ndidi's Blog | Tagged , , , , , , | 1 Comment

What can Scala do for you?

There are many new languages on the Java platform alongside the official Java language. Many have heard about Scala and many are considering using it in their code. So, how can Scala make your systems better? Is it really incredibly complex language that is simply far too difficult to use? Is it only suitable for very niche areas of development? Or is it a true general-purpose language, the Java of the future?

What is Scala

Scala is a type-safe, object-functional language. Scala allows you to build scalable (no, really?) systems by attempting to address the complexity of large systems. Its functional nature allows you to focus on the procedures in your system rather than the components in which these procedures live. Finally, Scala remains object-orieted, giving you the familiar inheritance, encapsulation and polymorphism.

In Scala, a functions is a first-class type; and as such can be assigned to a variable or passed as argument. You can kiss good-bye to the anonymous implementations of interfaces containing exactly one method: replace them with functions. But Scala goes further: its functions can accept functions as parameters and return functions; you can supply only some parameters of a function and the Scala compiler will create a new function that takes the remaining parameters! Finally, Scala functions can also have multiple parameter lists!

def curry(i: Int)(j: Int) = i * j
val f = (x: Double, y: Double) => x * y
val fWithXEq5 = f(5, _: Double)
val oneTimeX = curry(1)_

fWithXEq5(3)   // == 15
curry(1)(2)    // == 2
oneTimeX(2)    // == 2

In Scala, you compose functionality through composition inheritance. You can think of this as multiple implementation inheritance with some terms and conditions; the closest equivalent in Java would be an interface with method bodies. With careful design, you can inject functionality to the objects that you construct; while keeping the elements (traits in Scala speak) completely isolated and independent.

trait Speakable {
  def sound: String

  def speak() {
    val voice = VoiceManager.getInstance().getVoice("kevin16")
    voice.allocate()
    voice.speak(sound)
    voice.deallocate()
  }
}

abstract class Animal {
  def sound: String
}
class Dog extends Animal {
  def sound = "Woof"
}
class Cat extends Animal {
  def sound = "Meow"
}
class SpeakingCat extends Cat with Speakable 

val cat = new Cat with Speakable
val dog = new Dog with Speakable
val muteDog = new Dog
val speakingCat = new SpeakingCat

cat.speak()           // OK, meows
dog.speak()           // OK, woofs
speakingCat.speak()   // OK, meows
muteDog.speak()       // Does not compile

Notice that I was able to mix-in the Speakable trait to either individual instances or create a new subclass of Cat with the speaking trait mixed-in.

You can also express meaning in the types in your code; meaning that in Java is impossible to convey in the source code and we must rely on the programmers’ common sense.

abstract class Animal {
  type SuitableFood <: Food
}
class Cat extends Animal {
  type SuitableFood = CatFood
}
class Dog extends Animal {
  type SuitableFood = DogFood
}

abstract class Food
class CatFood extends Food
class LuxuryCatFood extends CatFood
class DogFood extends Food

def feed[A <: Animal, F <: A#SuitableFood](animal: A, food: F) =
  // somehow feed food to animal

I have expressed the common sense knowledge that a cat will eat cat food (just about), it will certainly eat luxury cat food, but will not touch dog food. The function feed enforces this at compile time!

feed(new Cat, new CatFood)       // OK
feed(new Cat, new LuxuryCatFood) // OK
feed(new Cat, new DogFood)       // Don't be silly; does not compile!

See! Too complicated

You might be thinking, “this is exactly the complexity I don’t want in my code!” Yes, the code I’ve shown is more complex than your Java code, but it does so much more! It is impossible to express the concepts I’ve shown in Java as clearly and as succinctly as I can do in Scala. Yes, Scala code can be complex, but not because the language is inherently and needlessly complex, but because it can solve very complicated problems.

All right, it’s not complex, but it’s not really useful

Scala is brilliantly useful, because it compiles to the standard Java byte code and because it can use all your existing Java code. Combine Java and Scala and implement polyglot codebase that uses the best language to solve your problems! Look–you can even have use Scala with Spring Framework!

@Controller
class UserController @Autowired() (private val userService: UserService) {

  @RequestMapping(value = "/users", method = RequestMethod.GET)
  @ModelAttribute("users")
  def index = userService.findAll

}

Find out more!

Try out Scala, ask us for advice, guidance and mentoring, and you will have polyglot codebase that uses the best language to solve your problems! I’d be delighted to show you how to combine Scala in traditional Java EE applications either by implementing discrete portion of your application in Scala or even implementing most of your application in Scala, but using your existing Java.

Posted in Jan's Blog | Tagged , , , , | Leave a comment