Wednesday, October 16, 2013

Play Framework on Heroku and custom dependencies

Today I was playing a little about Play Framework. This is very nice lightweight application framework for Java and Scala. I was trying to make an app and deploy to Heroku, which is a PaaS platform where you can host you Play applications for free (with some limitations of course).

And here the problem happened. For the project I use my own lib, managed by maven, let's say:

<groupId>com.blogspot.lifeinide</groupId>
<artifactId>mylib</artifactId>
<version>1.0-SNAPSHOT</version>
 
Now, how to use this lib for local Play project and then deploy it to Heroku with this dependency too? I don't want to put each time the new version to Play lib/ folder (it can be anyway cleaned up by "play dependencies") because this is still under development too. How to automate this? It is a bit tricky.

Play Framework uses its own dependency resolving mechanism based on dependencies.yml file, but internally it uses maven too. The key here is to configure appropriately dependencies.yml to use different maven repository, for example:

require:
    - play 1.2.5.3
    - com.blogspot.lifeinide -> mylib 1.0-SNAPSHOT
 
repositories:
    - jboss:
        type: iBiblio
        root: "file://${user.home}/.m2/repository/"
        contains:
            - com.blogspot.lifeinide -> *
 

Now you can "mvn install" your project to your local maven repository, and Play dependency system can find it.

But Heroku can't...

But here is the trick for Heroku. In my heroku project I have following structure:

|- heroku    // my heroku project
  |- .git    // git repository for heroku deployment
  |- repo    // this is my local maven repository

Now for the mylib project pom.xml I can configure appropriate deployment:

<build>
  <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.7</version>
        </plugin>
    </plugins>
</build>
 
<distributionManagement>
  <repository>
    <id>local-lib-unmanaged</id>
    <name>local-lib-unmanaged</name>
    <url>file:///path/to/heroku/repo</url>
  </repository>
</distributionManagement>

So it basically deploys the artifact to my local "repo" repository under heroku project on "mvn deploy". Now the changes in dependencies.yml:

require:
    - play 1.2.5.3
    - com.blogspot.lifeinide -> mylib 1.0-SNAPSHOT
 
repositories:
    - jboss:
        type: iBiblio
        root: "file://${application.path}/repo/"
        contains:
            - com.blogspot.lifeinide -> *

And here you are. After adding the "repo" to git and pushing all this stuff to Heroku, it can resolve dependencies.

No comments:

Post a Comment