<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3023258663364548527</id><updated>2024-09-01T20:52:24.310-07:00</updated><title type='text'>Cristian&#39;s Blog</title><subtitle type='html'>Mostly technobabble ...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-1084674957861642320</id><published>2015-09-30T13:46:00.000-07:00</published><updated>2015-09-30T13:46:22.382-07:00</updated><title type='text'>Publishing custom artifacts with SBT</title><content type='html'>In today&#39;s world the code is packaged and re-packaged in different ways. The code is typically packaged in a jar file. Along with that there is another jar file for the sources, and another for the javadoc. But then an application will use more than one jar along with other resources which results in the need for a &quot;distribution&quot; which is typically a zip file with a bunch of resources copied in the appropriate structure to be run. But then there is Docker which yet another packaging solution for delivering the application. With docker you would re-package the distribution in a different format. All these files need to be published to some repository as part of the build or release process.&lt;br /&gt;
I guess typically, the UI is last piece that with the most dependencies in a large application. In my Company for instance we develop the back-end code using plain Java and Maven and UIs using Play Framework and SBT. There is always the possibility of Mavenizing the Play project but somehow I never liked to complicate things when there is no absolute need for it.&lt;br /&gt;
When it comes to dependency management, the Maven builds will publish their artifacts in a repository (Artifactory for instance) and the UI will use the artifacts via managed dependencies.&lt;br /&gt;
SBT then compiles and packages the UI code and the resulting artifacts can be published to Artifactory via the simple &quot;publish&quot; command.&lt;br /&gt;
There are however some gaps here, and they all can be solved with a few lines of code in your build.sbt. :&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Play will generate multiple jar files but not all are published by default. For instance, try creating a Play module that is not just code, but is a full Play app complete with images, CSS and other assets. Play will package the assets separately from the project jar. It all works fine if you use a distribution created via &quot;dist&quot; because Play knows to add all the jars. But if you try to use the application as a dependency in another, you will need the assets jar which is not typically published. Fortunately it does not take too much code to convince SBT to do so. So once you encounter the problem you will ask Google for a solution and you will find that adding this to your build.sbt will result in publishing the assets jar too:&lt;br /&gt;&lt;pre style=&quot;background-color: #2b2b2b; color: #a9b7c6; font-family: &#39;Courier New&#39;; font-size: 9.0pt;&quot;&gt;packagedArtifacts in publish := {
  &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;val &lt;/span&gt;artifacts: Map[sbt.Artifact&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;java.io.File] = (packagedArtifacts in publish).value
  &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;val &lt;/span&gt;assets: java.io.File = (playPackageAssets in Compile).value
  artifacts + (Artifact(moduleName.value&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;jar&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;jar&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;assets&quot;&lt;/span&gt;) -&amp;gt; assets)
}&lt;/pre&gt;
Then you can add both the regular artifact and the asset jar as a dependency (note the &quot;assets&quot; classifier):&lt;br /&gt;&lt;pre style=&quot;background-color: #2b2b2b; color: #a9b7c6; font-family: &#39;Courier New&#39;; font-size: 9.0pt;&quot;&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;libraryDependencies &lt;/span&gt;++= &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;Seq&lt;/span&gt;(
  &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;com.acme&quot; &lt;/span&gt;%% &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;foo&quot; &lt;/span&gt;% &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;com.acme&quot; &lt;/span&gt;%% &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;foo&quot; &lt;/span&gt;% &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;classifier &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;assets&quot;&lt;/span&gt;)&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Play/SBT do a nice job of generating a distribution. The distribution step, however is not included in the release process (see sbt-release plugin). This can be fixed easily by customizing the release process:&lt;br /&gt;&lt;pre style=&quot;background-color: #2b2b2b; color: #a9b7c6; font-family: &#39;Courier New&#39;; font-size: 9.0pt;&quot;&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;releaseProcess &lt;/span&gt;:= &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;Seq&lt;/span&gt;[ReleaseStep](
  &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;checkSnapshotDependencies&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;inquireVersions&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;// runTest,           // do not run tests - assume everything is perfect&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;setReleaseVersion&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;commitReleaseVersion&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;tagRelease&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;releaseStepTask&lt;/span&gt;(&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;dist &lt;/span&gt;in myapp)&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;// create distribution&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publishArtifacts&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;setNextVersion&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;commitNextVersion&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;pushChanges&lt;/span&gt;)&lt;/pre&gt;
In the above snippet I am removing the test phase because we are automatically running tests as part of each commit so when it gets to release, everything is in order. This is just to speed up things.&lt;br /&gt;Also, I am adding a step for creating the distribution. This step need to be run before the version is changed or the zip file name will be stamped with the next version. You&#39;ll see later why I do it before publishing artifacts as well.&lt;/li&gt;
&lt;li&gt;Now the &amp;nbsp;zip file is created but it is not included in the list of artifacts being published. Oh well, the trick at point 1) can be applied here too. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;I don&#39;t know about others but I do not like to mix jars with distributions so I really wanted to publish the distribution to a different repository. This also is fixable and you can find the solution on &lt;a href=&quot;http://stackoverflow.com/questions/20985519/how-to-publish-to-multiple-repositories-in-sbt&quot; target=&quot;_blank&quot;&gt;stackoverflow&lt;/a&gt;. The idea is that you can create a custom task that extends the &quot;publish&quot; task and overrides the &quot;publishTo&quot; setting. &amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Finally, since I am working on a relatively large project, there are in fact multiple submodule/applications that are being built and they do not always need to be deployed together. As such, I am creating multiple distributions that package different components. So now I need to put it all together - publish multiple distributions to a different repository during the release process.&lt;br /&gt;&lt;pre style=&quot;background-color: #2b2b2b; color: #a9b7c6; font-family: &#39;Courier New&#39;; font-size: 9.0pt;&quot;&gt;&lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;lazy val &lt;/span&gt;publishDist = taskKey[&lt;span style=&quot;color: #cc7832;&quot;&gt;Unit&lt;/span&gt;](&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;Publish distributions - Custom Task&quot;&lt;/span&gt;)
publishDist := {
  &lt;span style=&quot;font-style: italic;&quot;&gt;println&lt;/span&gt;(&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;Publishing distributions ...&quot;&lt;/span&gt;)
  &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;val &lt;/span&gt;extracted = Project.&lt;span style=&quot;font-style: italic;&quot;&gt;extract&lt;/span&gt;(&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;state&lt;/span&gt;.value)
  Project.&lt;span style=&quot;font-style: italic;&quot;&gt;runTask&lt;/span&gt;(&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publish&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;extracted.append(&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;List&lt;/span&gt;(
    &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publishTo &lt;/span&gt;:= &lt;span style=&quot;font-style: italic;&quot;&gt;Some&lt;/span&gt;(&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;distributions&quot; &lt;/span&gt;at &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;distRepo&lt;/span&gt;)&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publishMavenStyle &lt;/span&gt;:= &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publishArtifact &lt;/span&gt;in Compile := &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publishArtifact &lt;/span&gt;in Test := &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publishArtifact &lt;/span&gt;in &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;Universal &lt;/span&gt;:= &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;packagedArtifacts &lt;/span&gt;in &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publish &lt;/span&gt;:= {
    &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;val &lt;/span&gt;artifacts: &lt;span style=&quot;color: #4e807d;&quot;&gt;Map&lt;/span&gt;[sbt.Artifact&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;java.io.File] = 
&lt;blockquote style=&quot;border: none; margin: 0 0 0 40px; padding: 0px;&quot;&gt;
&lt;blockquote style=&quot;border: none; margin: 0 0 0 40px; padding: 0px;&quot;&gt;
(&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;packagedArtifacts &lt;/span&gt;in &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publish&lt;/span&gt;).value&lt;/blockquote&gt;
&lt;/blockquote&gt;
artifacts +
          (&lt;span style=&quot;font-style: italic;&quot;&gt;Artifact&lt;/span&gt;(&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;zip&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;zip&quot;&lt;/span&gt;) -&amp;gt;
            &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;baseDirectory&lt;/span&gt;.value / &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;target&quot; &lt;/span&gt;/ &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;universal&quot; &lt;/span&gt;/ (&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;root-&quot; &lt;/span&gt;+ &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;version&lt;/span&gt;.value + &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;.zip&quot;&lt;/span&gt;)) +
          (&lt;span style=&quot;font-style: italic;&quot;&gt;Artifact&lt;/span&gt;(&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;submodule1&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;zip&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;zip&quot;&lt;/span&gt;) -&amp;gt;
            &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;baseDirectory&lt;/span&gt;.value / &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;modules/submodule1/target&quot; &lt;/span&gt;/ &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;universal&quot; &lt;/span&gt;/ (&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;submodule1-&quot; &lt;/span&gt;+ &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;version&lt;/span&gt;.value + &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;.zip&quot;&lt;/span&gt;)) +
          (&lt;span style=&quot;font-style: italic;&quot;&gt;Artifact&lt;/span&gt;(&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;submodule1&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;zip&quot;&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;zip&quot;&lt;/span&gt;) -&amp;gt;
            &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;baseDirectory&lt;/span&gt;.value / &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;modules/submodule2/target&quot; &lt;/span&gt;/ &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;universal&quot; &lt;/span&gt;/ (&lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;submodule2-&quot; &lt;/span&gt;+ &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;version&lt;/span&gt;.value + &lt;span style=&quot;color: #6a8759;&quot;&gt;&quot;.zip&quot;&lt;/span&gt;)) +
    }
  )&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;state&lt;/span&gt;.value)&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;true&lt;/span&gt;)
}&lt;/pre&gt;
Here I am adding to SBT&#39;s default list of artifacts my files - the zips along with customizations on where and how to publish.&lt;br /&gt;This task can be invoked manually in the activator console, but I created it so that I can invoke it as part of the release process. It is important that the task is invoked after the distributions are created:&lt;br /&gt;&lt;pre style=&quot;background-color: #2b2b2b; color: #a9b7c6; font-family: &#39;Courier New&#39;; font-size: 9.0pt;&quot;&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;releaseProcess &lt;/span&gt;:= &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;Seq&lt;/span&gt;[ReleaseStep](
  &lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;checkSnapshotDependencies&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;inquireVersions&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;// runTest,           // do not run tests - assume everything is perfect&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;setReleaseVersion&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;commitReleaseVersion&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;tagRelease&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;releaseStepTask&lt;/span&gt;(&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;dist &lt;/span&gt;in root)&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;releaseStepTask&lt;/span&gt;(&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;dist &lt;/span&gt;in submodule1)&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;releaseStepTask&lt;/span&gt;(&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;dist &lt;/span&gt;in submodule2)&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;publishArtifacts&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;releaseStepTask&lt;/span&gt;(publishDist)&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;// publish the distributions to Artifactory&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;setNextVersion&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;commitNextVersion&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #9876aa; font-style: italic;&quot;&gt;pushChanges&lt;/span&gt;)&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
As it&#39;s always the case with SBT it looks easy and obvious when done, but it&#39;s not as obvious when you are not very clear on its concepts.</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/1084674957861642320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/1084674957861642320' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1084674957861642320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1084674957861642320'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2015/09/publishing-custom-artifacts-with-sbt.html' title='Publishing custom artifacts with SBT'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-4831427233040097137</id><published>2014-02-04T19:16:00.003-08:00</published><updated>2014-02-04T19:16:48.703-08:00</updated><title type='text'>Play 2.2 subprojects and their assets</title><content type='html'>Yes, I still like Play! very much. But sometimes it is frustrating in its lackluster documentation. I spent literally hours trying to understand how to work with sub-projects. The fact that I could not find a step-by-step tutorial did not help (note to self - create one!)&lt;br /&gt;
I followed the documentation and created the top project, then subprojects. Then created dependencies. Btw, if you want to generate the eclipse projects from console make sure you do not aggregate the projects. For some reason, whenever I add &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;aggregate(subproj1, subproj2)&lt;/span&gt; to the top level poject in build.sbt it will omit some projects.&lt;br /&gt;
All good, projects compile, and run. But now it is important to take a look at the packages - make sure you refactor your code and move all controllers in subproj1 into their own package (ie. controllers.subproj1). Then, do the same for the scala.html files in views. You should end up with something like this:&lt;br /&gt;
&lt;pre&gt;multiproj
 build.sbt
 app
   controllers
     Application.java
   views
     index.scala.html
     main.scala.html
   conf
     application.conf
     routes
   public
     images
        ...
     stylesheets
        ...
     javascripts
        ...
   modules
     core
       build.sbt
       app
         controllers.core
           Application.java
         views.core
           index.scala.html
           main.scala.html
       conf
         application.conf
         core.routes
       public
          ...
     test
       build.sbt
       app
         controllers.test
           Application.java
         views.test
           index.scala.html
           main.scala.html
       conf
         application.conf
         core.routes
       public
          ...
&lt;/pre&gt;
&lt;br /&gt;
and the top build.sbt looks like this:
&lt;br /&gt;
&lt;pre&gt;name := &quot;multiproj&quot;

version := &quot;1.0-SNAPSHOT&quot;

libraryDependencies ++= Seq(
 javaCore, cache
)     

play.Project.playJavaSettings

lazy val root = project.in(file(&quot;.&quot;)).dependsOn(core, test)

lazy val core = project.in(file(&quot;modules/core&quot;))

lazy val test = project.in(file(&quot;modules/test&quot;)).dependsOn(core)
&lt;/pre&gt;
&lt;br /&gt;
and the top routes file:
&lt;br /&gt;
&lt;pre&gt;GET     /                           controllers.Application.index()
-&amp;gt; /core core.Routes
-&amp;gt; /test test.Routes
# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path=&quot;/public&quot;, file)
&lt;/pre&gt;
&lt;br /&gt;
Obviously, the core and test routes files must use proper packages when referring to the controller classes.
So far, it is not that bad. 
But what about the resources? Notice how the same top level public folder is invoked above. Well, there is an extra step - create an Assets class in the controllers.core and controllers.test that will help scope the lookup to the project directory. Play documentation nicely provides the contents of this class:
&lt;br /&gt;
&lt;pre&gt;package controllers.test;

import play.api.mvc.Action;
import play.api.mvc.AnyContent;

public class Assets {
    public static Action&lt;anycontent&gt; at(String path, String file) {
        return controllers.Assets.at(path, file);
    }
}
&lt;/anycontent&gt;&lt;/pre&gt;
&lt;br /&gt;
and now update the route in the test.routes accordingly:
&lt;br /&gt;
&lt;pre&gt;GET     /assets/*file               controllers.test.Assets.at(path=&quot;/public&quot;, file)
&lt;/pre&gt;
&lt;br /&gt;
Make change in the stylesheet from top level project and you will see it applied. Now change the color in the stylesheet from test project and nothing happens. WTF?!?!&lt;br /&gt;
&lt;br /&gt;
Well, as it turns out, Play uses the same classloader to load the files, so if the file name from top level and subproject is the same, it is not going to work.
Thus, it is important that the assets from subprojects (public folders from subprojects) have unique names. You can follow the same scheme as for routes file and have public/main.css in top level project and public/test.main.css in the test subprojects. 
Then you will need to make sure you use the proper reverse routing in the template. Example: &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@controllers.test.routes.Assets.at(&quot;stylesheets/test.main.css&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Bottom line, yes you can split your application in sub-projects and be organized, but I am a bit disappointed in the number of hoops I have to jump to make it go. It should be simpler, Play!. Please make it more straight-forward! I would suggest that the console should know about sub-projects and pre-create the right structure and naming... Can&#39;t be that hard to make the console do all the renaming steps above.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;http://www.playframework.com/documentation/2.2.x/SBTSubProjects&lt;/li&gt;
&lt;li&gt;https://github.com/playframework/playframework/issues/1181&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/4831427233040097137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/4831427233040097137' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/4831427233040097137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/4831427233040097137'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2014/02/play-22-subprojects-and-their-assets.html' title='Play 2.2 subprojects and their assets'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-1687744327147262482</id><published>2013-03-14T08:15:00.000-07:00</published><updated>2013-03-14T08:15:05.188-07:00</updated><title type='text'>Play and JAAS </title><content type='html'>I blogged in the past about Play and JAAS. I have actually created a Play module in GitHub (&lt;a href=&quot;https://github.com/cduicu/play-jaas&quot;&gt;https://github.com/cduicu/play-jaas&lt;/a&gt;) &amp;nbsp;that can do JAAS style authentication in a Play application. Recently I have updated the module for Play 2.1 as well as fixing one important multi-threaded bug.&lt;br /&gt;
You see, I was lazy and I was passing the Http.Context via a static in order to have access to it in the callback and the login module. But this is wrong as it makes the login module thread unsafe! This was fix in the last commit and the context is now passed via callback handler to callback and then to auth module.</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/1687744327147262482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/1687744327147262482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1687744327147262482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1687744327147262482'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2013/03/play-and-jaas.html' title='Play and JAAS '/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-4911175883015190983</id><published>2013-02-07T07:26:00.000-08:00</published><updated>2013-02-07T07:26:11.470-08:00</updated><title type='text'>Play 2.0.x Module</title><content type='html'>During development one always finds themselves in the position of creating reusable code. For Play, I have a project containing a lot of the boilerplate code that I want to share among many concrete Play applications. One solution is to create a regular Play project (I&#39;ll refer to it as &quot;playcommons&quot;) and set-up project dependency between your application and &amp;nbsp;the playcommons project. See &lt;a href=&quot;http://cduicu.blogspot.ca/2012/05/play2-project-dependency.html&quot;&gt;here&lt;/a&gt; for more details. However, managing the versions of the playcommons is not straight-forward.&lt;br /&gt;
Another solution is to make the playcommons project a Play module. This way, the project can be compiled and published and therefore the versions will be managed via the repository. I did not find some clear documentation on Play website on creating modules but here is a good article on the subject:&amp;nbsp;&lt;a href=&quot;http://www.objectify.be/wordpress/?p=363&quot;&gt;http://www.objectify.be/wordpress/?p=363&lt;/a&gt;.&lt;br /&gt;
In the end, you can either get the packaged jar of the module and include it in the Play application (this way you don&#39;t have to manage a repository) or publish the module in a repository and then manage the dependency via Ivy in Build.scala.</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/4911175883015190983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/4911175883015190983' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/4911175883015190983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/4911175883015190983'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2013/02/play-20x-module.html' title='Play 2.0.x Module'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-3949579342642931720</id><published>2013-01-31T06:14:00.004-08:00</published><updated>2013-01-31T06:14:55.194-08:00</updated><title type='text'>The Big Data Landscape</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
I did not make this, but I do find it interesting.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjrbrX1VNP-8rPi55ITKrJm4pzNhZguxGjHNidcl5B4KDA_Zw1nf8H2u4L-VfVZKHoXgKijnQhWsY-5qxzg0eOwRsk2kNWtiVKY3K7ULJ12pqSKfedhL7EJOFeNdKaM3Uv914BgvVATfU/s1600/The+Big+Data+Landscape.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjrbrX1VNP-8rPi55ITKrJm4pzNhZguxGjHNidcl5B4KDA_Zw1nf8H2u4L-VfVZKHoXgKijnQhWsY-5qxzg0eOwRsk2kNWtiVKY3K7ULJ12pqSKfedhL7EJOFeNdKaM3Uv914BgvVATfU/s1600/The+Big+Data+Landscape.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/3949579342642931720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/3949579342642931720' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/3949579342642931720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/3949579342642931720'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2013/01/the-big-data-landscape.html' title='The Big Data Landscape'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjrbrX1VNP-8rPi55ITKrJm4pzNhZguxGjHNidcl5B4KDA_Zw1nf8H2u4L-VfVZKHoXgKijnQhWsY-5qxzg0eOwRsk2kNWtiVKY3K7ULJ12pqSKfedhL7EJOFeNdKaM3Uv914BgvVATfU/s72-c/The+Big+Data+Landscape.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-6304015489524936196</id><published>2013-01-30T06:59:00.002-08:00</published><updated>2013-01-30T06:59:47.170-08:00</updated><title type='text'>DataTables Fixed Height</title><content type='html'>I&#39;ve already confessed that I am a big fan of Twitter Bootstrap and jQuery. In my apps I often deal with tables and grids. In the past I was using the wonderful ExtJS grid. But ExtJS is rather heavy and it does not play well with Bootstrap. So I was looking at alternatives, and there is a nice (and free!) jQuery Plugin for this: &lt;a href=&quot;http://datatables.net/&quot;&gt;DataTables&lt;/a&gt;.&lt;br /&gt;
While DataTables gives you a lot of flexibility I could not find a nice way of having the table&#39;s height fixed. There is a &lt;a href=&quot;http://www.datatables.net/forums/discussion/12187/datatable-fixed-height/p1&quot;&gt;discussion on their forum&lt;/a&gt; for this topic but the solution did not work that well for me so I came up with a simpler alternative that seems to work well. The following JS snippet refers to the examples on DataTables website.&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$table = $(&#39;#example&#39;);
$table.dataTable( {
  &quot;sDom&quot;: &#39;tif&#39;, 
  &quot;bScrollInfinite&quot;: true, 
  &quot;bScrollCollapse&quot;: true, 
  &quot;sScrollY&quot;: &quot;200px&quot;,
  &quot;oLanguage&quot;: { 
    &quot;sLengthMenu&quot;: &quot;_MENU_ / page&quot;,
 &quot;sInfo&quot;: &quot;(_START_ to _END_) of _TOTAL_&quot;,
 &quot;sSearch&quot;: &quot;&quot;
  }
  ,&quot;fnDrawCallback&quot;: function() {
        $table.dataTable()._fnScrollDraw();        
        $table.closest(&quot;.dataTables_scrollBody&quot;).height(200);
   }  
} );&lt;/pre&gt;
From the snippet above, only the fnDrawCallback is important. It will fix the table&#39;s height to 200px as instructed in the scroller configuration. The trick is to let the component do its work and then simply adjust the height of the scroller element.&lt;br /&gt;
A better version would not duplicate the height and would reuse the value configured in sScrollY property, but I did not find yet how to access it.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/6304015489524936196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/6304015489524936196' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/6304015489524936196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/6304015489524936196'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2013/01/datatables-fixed-height.html' title='DataTables Fixed Height'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-560972429132938608</id><published>2013-01-23T13:28:00.000-08:00</published><updated>2013-01-23T13:28:05.598-08:00</updated><title type='text'>Inline editable fields for an HTML table</title><content type='html'>I am a fan of &lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Twitter&#39;s Bootstrap&lt;/a&gt;. It is simply fantastic. But you can make it more powerful if you use jQuery plugins and Bootstrap extensions. So here is &lt;a href=&quot;http://bootsnipp.com/resources&quot;&gt;Bootsnipp&lt;/a&gt; - a site that lists cool Bootstrap extensions.&lt;br /&gt;
Traditionally on the web, when you want to capture information from the user you have to create a form. This is great, but sometimes building a form is not that natural. Sometimes we want to edit a value in the middle of a text, or edit the value from a table. There are a lot of solutions out there, and this is just one of them using Bootstrap and a neat extension named &lt;a href=&quot;http://vitalets.github.com/x-editable/index.html&quot;&gt;X-editable&lt;/a&gt;.&lt;br /&gt;
While the X-editable site shows a lot of examples, I could not find a way to make my table handle more like a form. What this means is that I want to edit the fields in the table without posting the changes and have a &quot;Save&quot; and &quot;Reset&quot; buttons to apply the changes or revert to the original values.&lt;br /&gt;
The &quot;Save&quot; button is nicely demo-ed on X-editable site but the reset functionality was not to my liking as the example is not truly reverting the values to their original state, but instead it is setting them to null (which is fine for that example as it deals with creating a new entry).&lt;br /&gt;
Then I realized that the library does not save the original value and it is lost. So I plugged in my handlers for save and reset in order to add my desired functionality.The trick is that I save the original value in the element itself on the &quot;save&quot; event and then make sure I clean it up when the processing completes (either successfully or the reset is invoked). My example also extends the original example and looks for next editable item on the rows as well as columns.&lt;br /&gt;
&lt;div&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;// this is to automatically make the next item in the table editable
$(&#39;.edit&#39;).on(&#39;save&#39;, function(e, params){
    var that = this;
    // persist the old value in the element to be restored when clicking reset
    var oldItemValue = $(that)[0].innerHTML;
    if (!$(that).attr(&#39;oldValue&#39;)) {
     $(that).attr(&#39;oldValue&#39;, oldItemValue);
    }
    setTimeout(function() {
        // first search the row
        var item = $(that).closest(&#39;td&#39;).next().find(&#39;.edit&#39;);
        console.log(item);
        if (item.length == 0) {
            // check the next row
            item = $(that).closest(&#39;tr&#39;).next().find(&#39;.edit&#39;);
        }
        item.editable(&#39;show&#39;);
    }, 200);
});
&lt;/pre&gt;
The &quot;Reset&quot; button handler:&lt;/div&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$(&#39;#resetbtn&#39;).click(function() {
    $(&#39;.edit&#39;).each(function() {
        var o = $(this);
        o.editable(&#39;setValue&#39;, o.attr(&#39;oldValue&#39;)) //clear values
         .editable(&#39;option&#39;, &#39;pk&#39;, o.attr(&#39;pk&#39;)) //clear pk
         .removeClass(&#39;editable-unsaved&#39;)
      .removeAttr(&#39;oldValue&#39;);
    });
});
&lt;/pre&gt;
And the &quot;Save&quot; button handler:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$(&#39;#savebtn&#39;).click(function() {
   $(&#39;.edit&#39;).editable(&#39;submit&#39;, { 
       url: &#39;/post&#39;, 
       //ajaxOptions: { dataType: &#39;json&#39; },           
       success: function(data, config) {
           $(this).removeClass(&#39;editable-unsaved&#39;) //remove unsaved class
               .removeAttr(&#39;oldValue&#39;); // clear oldValue
       },
       error: function(errors) {
           console.log(&#39;error&#39;);
           var msg = &#39;&#39;;
           if(errors &amp;amp;&amp;amp; errors.responseText) { //ajax error, errors = xhr object
               msg = errors.responseText;
           } else { //validation error (client-side or server-side)
               $.each(errors, function(k, v) { msg += k+&quot;: &quot;+v+&quot;
&quot;; });
           } 
       }
   });
});
&lt;/pre&gt;
You can find the code and a demo &lt;a href=&quot;http://jsfiddle.net/cduicu/3KkZd/&quot;&gt;here&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/560972429132938608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/560972429132938608' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/560972429132938608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/560972429132938608'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2013/01/inline-editable-fields-for-html-table.html' title='Inline editable fields for an HTML table'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-1794887305435031383</id><published>2013-01-15T12:53:00.002-08:00</published><updated>2013-01-15T12:53:25.456-08:00</updated><title type='text'>Play Framework 2.0.3 to 2.1 RC2 upgrade</title><content type='html'>If you were expecting that upgrading your Play project from 2.0.x to 2.1 will be a simple replacement of the play libraries you will be&amp;nbsp;disappointed. But don&#39;t worry, as it is not that bad. Here is a mini guide for the upgrade.&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;Download &lt;a href=&quot;http://www.blogger.com/goog_1567703041&quot;&gt;Play Framework&amp;nbsp;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, sans-serif; font-size: x-small;&quot;&gt;&lt;a href=&quot;http://download.playframework.org/releases/play-2.1-RC2.zip&quot;&gt;2.1RC2&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;Edit &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[yourApp]/project/plugins.sbt&lt;/span&gt; file and set SBT version to &quot;2.1-RC2&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;Edit &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[yourApp]/project/build.properties&lt;/span&gt; file and set SBT version to “0.12.2-RC2”&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;The &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[yourApp]/project/Build.scala&lt;/span&gt;&amp;nbsp;file needs to be updated to remove a warning about “using a deprecated version of
Play&#39;s SBT Project”. To do this you will need to:&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;Replace “&lt;/span&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;import PlayProject._&lt;/span&gt;&lt;span style=&quot;color: #595959;&quot;&gt;” &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;with “&lt;/span&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;import play.Project._&lt;/span&gt;”&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;Update appDependencies object value and make sure the sequence contains&amp;nbsp;&lt;/span&gt;&quot;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;javaCore, javaJdbc, javaEbean&lt;/span&gt;&quot;.&lt;br /&gt;Example:&lt;br /&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;val appDependencies = Seq(javaCore, javaJdbc, javaEbean)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;Replace &lt;br /&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;“&lt;/span&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace; text-indent: -0.25in;&quot;&gt;val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA)&lt;/span&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;”&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;text-indent: -0.25in;&quot;&gt;with
&lt;br /&gt;“&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;val main = play.Project(appName, appVersion, appDependencies)&lt;/span&gt;”&lt;/span&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;margin-left: 1.0in; mso-list: l0 level2 lfo1; text-indent: -.25in;&quot;&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;mso-list: l0 level1 lfo1; text-indent: -.25in;&quot;&gt;
&lt;!--[if !supportLists]--&gt;1.&lt;span style=&quot;font-size: 7pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;!--[endif]--&gt;It
is recommended to run “&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;play clean-all&lt;/span&gt;” before compiling anything. This will
ensure a cleanup of sbt.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;A change in the API that will likely impact every application out there is in how you access the form. Every reference to &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Controller.form()&lt;/span&gt; will error as that is no longer available. Instead you should change your code to use &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;play.data.Form.form()&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Launch the play console and try and compile the application. You might get new warnings regarding your routes. They are just warnings but you should have a look at them.&lt;/li&gt;
&lt;li&gt;If your code compiles and you are using Eclipse as your IDE of choice you should re-eclipsify your project as Play 2.1 will have a different classpath and a different set of libraries. Note that the old &quot;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;eclipsify&lt;/span&gt;&quot; command&amp;nbsp;is no longer available&amp;nbsp;as it&amp;nbsp;was replaced by &quot;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;eclipse&lt;/span&gt;&quot; command.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
If you are wondering about differences regarding classpath, tasks, commands between 2.0.3 and 2.1 RCs you can have a look &lt;a href=&quot;https://docs.google.com/spreadsheet/ccc?key=0Aq3GpP8JZivvdFFGUWdsaktRdWJPREZ4VEdyRnpQSVE&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;
&lt;div class=&quot;MsoListParagraph&quot; style=&quot;margin-left: 1.0in; mso-list: l0 level2 lfo1; text-indent: -.25in;&quot;&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/1794887305435031383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/1794887305435031383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1794887305435031383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1794887305435031383'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2013/01/play-framework-203-to-21-rc2-upgrade.html' title='Play Framework 2.0.3 to 2.1 RC2 upgrade'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-1497514021913248288</id><published>2013-01-11T11:58:00.003-08:00</published><updated>2013-01-11T11:58:59.067-08:00</updated><title type='text'>Thread Deadlock</title><content type='html'>Instead of long articles, here is a picture that describes the thread deadlock nice and clearly:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCnCiqatduV5GV154VhlS_QSMR9I1w2iSIscelHku1lPNOop-q-MrpVhOF1GMYnzTF8h-htAdxH9HeHQtaMgO41pEaZoyHu1jaY4xFaQ2rq74zF9Q7_kkdr9HnA-NxQ7LWDftJ3vfFBHw/s1600/deadlock.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;267&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCnCiqatduV5GV154VhlS_QSMR9I1w2iSIscelHku1lPNOop-q-MrpVhOF1GMYnzTF8h-htAdxH9HeHQtaMgO41pEaZoyHu1jaY4xFaQ2rq74zF9Q7_kkdr9HnA-NxQ7LWDftJ3vfFBHw/s400/deadlock.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Can&#39;t get simpler than that!</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/1497514021913248288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/1497514021913248288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1497514021913248288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1497514021913248288'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2013/01/thread-deadlock.html' title='Thread Deadlock'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCnCiqatduV5GV154VhlS_QSMR9I1w2iSIscelHku1lPNOop-q-MrpVhOF1GMYnzTF8h-htAdxH9HeHQtaMgO41pEaZoyHu1jaY4xFaQ2rq74zF9Q7_kkdr9HnA-NxQ7LWDftJ3vfFBHw/s72-c/deadlock.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-7448674790047535191</id><published>2012-09-28T06:29:00.001-07:00</published><updated>2012-09-28T06:29:26.270-07:00</updated><title type='text'>Variables in Scala files for Play 2.x</title><content type='html'>The scala html files for Play 2.x will eventually be compiled in classes/methods. Each one has a signature to allow type-safe parameter passing from controller to the view. But sometimes we need to include a script in the page and that is when the need for local variables may occur.&lt;br /&gt;
For instance I want to make sure I add HTML only if the object is not null. In JAVA this would be equivalent to:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
Feature f = features.getFeature(featureName);&lt;br /&gt;if (f != null) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;.... use the feature object ....&lt;br /&gt;}&lt;/blockquote&gt;
or if I need to iterate:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
for (Feature f : features) {&lt;br /&gt;&amp;nbsp; if (f == null) continue;&lt;br /&gt;&amp;nbsp; .... use the feature object ....&lt;br /&gt;}&lt;/blockquote&gt;
Note that I test the object for null and use &quot;continue&quot; instead of enclosing everything in the if block. It is a matter of preference - I think it makes the code more readable.&lt;br /&gt;
&lt;br /&gt;
Two problems arise when trying to do the same in Scala in the html pages:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;declaring local variables in Play scala pages is quite cumbersome&lt;/li&gt;
&lt;li&gt;there is no &quot;continue&quot; in Scala.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Here are a few workarounds for the issues mentioned above:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use &quot;Option&quot;. Option is a replacement for checking for null. The map is created only if not null. In this case a map of one element is created and is assigned to “feature”.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;@Option(features.getFeature(featureName)).map
{feature=&lt;u&gt;&amp;gt;&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/u&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Consolas; font-size: x-small;&quot;&gt;&lt;u&gt;........&lt;/u&gt;&lt;/span&gt;&lt;u&gt;&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;}&lt;/span&gt;&lt;/u&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;What if there are more that one?&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;@Option(features.getFeature(featureName)).map
{feature=&lt;u&gt;&amp;gt;&lt;/u&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Option(1).map (f2 =&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;You can also use for loops.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;@for(feature1 &lt;/span&gt;&lt;span style=&quot;color: teal; font-family: Consolas; font-size: 10.0pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;- Option(features.getFeature(featureName));&lt;/span&gt;&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;f2 &lt;/span&gt;&lt;span style=&quot;color: teal; font-family: Consolas; font-size: 10.0pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;- Option(1)) {&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Consolas; font-size: 10pt;&quot;&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;If List is used instead of Option, the for loop will be executed once for each item in the List.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;




&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/7448674790047535191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/7448674790047535191' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/7448674790047535191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/7448674790047535191'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2012/09/variables-in-scala-files-for-play-2x.html' title='Variables in Scala files for Play 2.x'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-7914893228854718196</id><published>2012-06-28T10:29:00.000-07:00</published><updated>2012-06-28T10:29:02.946-07:00</updated><title type='text'>Upgrade from Play 2.0.1 to 2.0.2</title><content type='html'>Say you have a project in Play 2.0.1, but guess what? There is a new (minor) version out there that might just fix a bug you care about. How do you go about upgrading?&lt;br /&gt;
Well, first you need to download the new Play 2.0.2 framework and replace the old one. Then, you need to edit a couple files in &amp;nbsp;your project in order to make it compatible:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;edit [appName]/project/build.properties and change sbt version from 0.11.2 to 0.11.3. Like this:&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;sbt.version=0.11.3&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;edit [appName]/project/plugins.sbt and change the version of play from 2.0.1 to 2.0.2. Like this:&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;addSbtPlugin(&quot;play&quot; % &quot;sbt-plugin&quot; % &quot;2.0.2&quot;)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
That&#39;s it! Now launch play again and you should see that it updates a bunch of libraries and then its&#39; ready.&lt;/div&gt;
&lt;div&gt;
Additionally if you are using Eclipse IDE, you might need to re-eclipsify your app in order to fix the Eclipse project classpath to point to the new 2.0.2 directory.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/7914893228854718196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/7914893228854718196' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/7914893228854718196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/7914893228854718196'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2012/06/upgrade-from-play-201-to-202.html' title='Upgrade from Play 2.0.1 to 2.0.2'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-1730148733971803536</id><published>2012-05-25T07:07:00.000-07:00</published><updated>2012-05-25T07:07:10.897-07:00</updated><title type='text'>Play2 Port Change</title><content type='html'>Play 2.0.1 defaults the port to 9000. But if you want to develop more that one app at a time you need to be able to change the port. Googling this you&#39;ll find the recommendation for typing in command line:&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;play &quot;run 9001&quot;&lt;/span&gt;&lt;br /&gt;
But this does not work in Windows. Until they fix this you need to do this in two steps. First enter the Play console with a simple:&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;play&lt;/span&gt;&lt;br /&gt;
then while in the Play console you can run the application with the port of your choice:&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;[appName] $ run 9001&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/1730148733971803536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/1730148733971803536' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1730148733971803536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/1730148733971803536'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2012/05/play2-port-change.html' title='Play2 Port Change'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-8604293693509498459</id><published>2012-05-25T06:26:00.001-07:00</published><updated>2012-05-25T06:26:11.068-07:00</updated><title type='text'>Play2 Project Dependency</title><content type='html'>I have recently started to use Play framework, and I quite like it. It may have its issues, but all in all it is a neat framework. Like many other developers out there I want to use it from within my favourite IDE - Eclipse. And Play makes that happen via it &quot;eclipsify&quot; command.&lt;br /&gt;
All is good, when you are working on a single application. But what happens when you want to create more than one application and you realize that you don&#39;t want to copy the boiler plate code in each of the project. Take the security feature for example. Each app will have to implement it and Play does provide the basics but there is still some code to be written. And I don&#39;t want to copy the file(s) each time a I create a new app.&lt;br /&gt;
Now Eclipse does have a neat feature where you can create project dependencies which means that all the classes from the project you depend on are added to the classpath of your current project. Great! That works fine for regular Java projects, but Play does its own building behind the scenes which has nothing to do with Eclipse&#39;s build.&lt;br /&gt;
There is however a way out. And it is quite simple. You see, each Play 2.x project will create the .class files in the &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;[project_dir]/target/scala-2.9.1/classes&lt;/span&gt;. (I suspect that the location will change later, when the scala version is updated).&lt;br /&gt;
Now let&#39;s say you have a project called &quot;common&quot; where you add all the utilities and boiler plate code. Then you have &quot;myApp&quot; where you want to use the code from &quot;common&quot; without copying it. In Eclipse, you go to Project Properties for &quot;myApp&quot;, &quot;Java Build Path&quot;, select &quot;Project&quot; tab and add the &quot;common&quot; project in the list of required projects. That takes care of the Eclipse side.&lt;br /&gt;
To make it work in Play, there is one other thing you need to do. Locate &quot;Build.scala&quot; file from &quot;myApp&quot; project (this will be in&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt; myApp/project/&lt;/span&gt; directory). This is the file that controls the Play build. you want to modify it and add the classes generated by &quot;common&quot; project to both runtime and compile classpaths. This is how you can do it:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;val wsdir = (new java.io.File(&quot;./..&quot;)).getCanonicalPath // workspace dir&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;val appDependencies = Seq(&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; // Add your project dependencies here,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; .settings(&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dependencyClasspath in Runtime ++= Seq(file(wsdir+&quot;/common/target/scala-2.9.1/classes&quot;))&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; .settings(&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dependencyClasspath in Compile ++= Seq(file(wsdir+&quot;/common/target/scala-2.9.1/classes&quot;))&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
Note that this code snippet assumes that projects &quot;myApp&quot; and &quot;common&quot; share a common parent directory.&lt;/div&gt;
&lt;div&gt;
And that&#39;s it for development. Creating the final build for production is another story and that depends on how you want to deploy your projects.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/8604293693509498459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/8604293693509498459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/8604293693509498459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/8604293693509498459'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2012/05/play2-project-dependency.html' title='Play2 Project Dependency'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-7195647290069731862</id><published>2012-05-24T12:49:00.000-07:00</published><updated>2012-05-24T12:49:26.249-07:00</updated><title type='text'>Single Sign On with SAML2</title><content type='html'>This is a complicated topic with a lot of information published in the form of articles all over the internet. While SSO can be done in various ways and with different technologies, it seems like the standard that has the most traction is the Web Browser SSO Profile in SAML2.&lt;br /&gt;
I find it odd that I could not find a good SSO or SAML book anywhere. Which makes it difficult for a beginner to tackle. There is a pretty good description of the process on &lt;a href=&quot;http://en.wikipedia.org/wiki/SAML_2.0#Web_Browser_SSO_Profile&quot;&gt;Wikipedia &lt;/a&gt;though.&lt;br /&gt;
Well one has to start somewhere so, being in the Java camp I looked for the options available to the Java programmer. As it turns out, if you want to go the SAML way there is an open source solution called &lt;a href=&quot;http://shibboleth.net/&quot;&gt;Shibboleth&lt;/a&gt;. This is based on &lt;a href=&quot;https://wiki.shibboleth.net/confluence/display/OpenSAML/Home/&quot;&gt;OpenSAML&amp;nbsp;&lt;/a&gt;&lt;br /&gt;
There is even a test Identity Provider (IdP) available on the internet: &lt;a href=&quot;https://www.testshib.org/testshib-two/index.jsp&quot;&gt;TestShib&lt;/a&gt;. However, since I was working on the company network behind firewalls I could not use it. As part of the sequence of events, the IdP needs to redirect to the Service Provider (SP) and that part did not work for my setup.&lt;br /&gt;
As such I downloaded and installed Shibboleth IdP in a Tomcat instance and gave it a go. I must say that while there isn&#39;t much code involved (or that complicated), what proved to be the most difficult part was the configuration of Shibboleth IdP and the metadata file. Once you get that right as well as the certificates, it is not much to it.&lt;br /&gt;
So while there are examples out there (perhaps better written or more complete) I created my own and put it in &amp;nbsp;GitHub. Check it out here:&lt;a href=&quot;https://github.com/cduicu/SAML2Authn&quot;&gt;&amp;nbsp;https://github.com/cduicu/SAML2Authn&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/7195647290069731862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/7195647290069731862' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/7195647290069731862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/7195647290069731862'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2012/05/single-sign-on-with-saml2.html' title='Single Sign On with SAML2'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3023258663364548527.post-8238477043515733675</id><published>2008-07-10T09:50:00.000-07:00</published><updated>2008-07-10T09:51:30.521-07:00</updated><title type='text'>Just started!</title><content type='html'>I&#39;ve nothing to say now ... just created the blog :).</content><link rel='replies' type='application/atom+xml' href='http://cduicu.blogspot.com/feeds/8238477043515733675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3023258663364548527/8238477043515733675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/8238477043515733675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3023258663364548527/posts/default/8238477043515733675'/><link rel='alternate' type='text/html' href='http://cduicu.blogspot.com/2008/07/just-started.html' title='Just started!'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15193585333961585123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>