<?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-8528942568460675966</id><updated>2024-10-25T01:46:36.557+02:00</updated><category term="jspc"/><category term="maven"/><category term="war"/><category term="git"/><category term="git-flow"/><category term="gradle"/><category term="jenkins"/><category term="maven security"/><category term="multi-project"/><title type='text'>Just build it</title><subtitle type='html'>I write mostly on some ways to build software. It has been mostly centered on Maven in the past but the focus is shifting more and more towards Gradle and other build tools.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://maventweaks.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://maventweaks.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/17001550261994560281</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>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8528942568460675966.post-2043881976385980188</id><published>2012-10-01T15:28:00.001+02:00</published><updated>2012-10-02T08:52:43.513+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="git"/><category scheme="http://www.blogger.com/atom/ns#" term="git-flow"/><category scheme="http://www.blogger.com/atom/ns#" term="jenkins"/><title type='text'>Fun with git remote branches</title><content type='html'>I am currently using the &lt;a href=&quot;https://github.com/entagen/jenkins-build-per-branch&quot; target=&quot;_blank&quot;&gt;build-per-branch-&quot;Plugin&quot;&lt;/a&gt;&amp;nbsp;to integrate my git-flow-enabled projects with Jenkins continuous integration.&lt;br /&gt;
&lt;br /&gt;
After creating and removing a few feature/hotfix/release branches I noted that some branches that should have been deleted kept returning in my list of Jenkins jobs.&lt;br /&gt;
&lt;br /&gt;
So, nobody likes zombie jobs, right?&lt;br /&gt;
&lt;br /&gt;
I started digging into the build-per-branch plugin. It uses &quot;git ls-remote --heads &lt;git:&gt;&quot; to retrieve the &amp;nbsp;list of remote branches.&amp;nbsp;&lt;/git:&gt;&lt;br /&gt;
And behold: my branches that &quot;git branch -r&quot; would no longer show were still listed there!&lt;br /&gt;
&lt;br /&gt;
I did delete the branches using &quot;git branch -r -d &lt;branch&gt;&quot; and it told me that the remote branch was removed.&lt;/branch&gt;&lt;br /&gt;
&lt;br /&gt;
There is the other way for deleting remote branches: Pushing an empty repository to a remote branch with &quot;git push origin :&lt;branch&gt;&quot; (I confess that I often have used &quot;git branch -r -d&quot; because I could remember it more easily).&amp;nbsp;&lt;/branch&gt;&lt;br /&gt;
&lt;br /&gt;
But as it turns out the only surefire way to get rid of a remote repository seems to be to use &quot;git push origin :&lt;branch name=&quot;name&quot;&gt;&quot;, becuase after this &quot;git ls-remote&quot; no longer lists the reference for the branch&#39;s head.&lt;/branch&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Update&lt;/b&gt;: I asked about this behavior ont the git mailing list:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;div class=&quot;p1&quot;&gt;







&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Hi,&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;I came across an issue with deleting remote branches: When deleting a&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;branch using &quot;git branch ­r ­d &lt;branch&gt;&quot; the branch is deleted and no&lt;/branch&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;longer shown by &quot;git branch ­r&quot;.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&quot;git ls-remote --heads&quot; on the other hand still lists the ref for the last&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;branch commit.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;If I delete the branch using &quot;git push origin :&lt;branch&gt;&quot; the branch is&lt;/branch&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;removed completely (i.e. git ls-remote&amp;nbsp;&amp;nbsp;no longer returns a ref).&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Is this a bug or is this behavior intentional? (I am currently using git&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;1.7.12).&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
Here is the response I got from the git mailing list:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;All of the above are expected and working as designed.&amp;nbsp;&amp;nbsp;Remote&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;tracking branches are local _copies_ of what you have over there at&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;the remote repository. The latter is the authoritative version, and&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;you asked &quot;ls-remote&quot; to go over the network to view them.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;If you are trying to remove the branches you show to others and&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;yourself who are observing that remote repository from your local&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;workstation, you can first &quot;git push origin :&lt;branch&gt;&quot; to remove it&lt;/branch&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;in the remote repository. You can run your next fetch with &quot;--prune&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;to get rid of remotes/origin/&lt;branch&gt;, I think.&lt;/branch&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
I think it clarifies the behavior. That thing that &quot;git branch -r -d&quot; deletes is only the local reference of the remote brach (the rempote tracking branch), i.e. the git branch command works fully locally.&lt;br /&gt;
&lt;br /&gt;
Only git push will really change &lt;b&gt;*anything*&lt;/b&gt; on a remote repository.</content><link rel='replies' type='application/atom+xml' href='http://maventweaks.blogspot.com/feeds/2043881976385980188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maventweaks.blogspot.com/2012/10/fun-with-git-remote-branches.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/2043881976385980188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/2043881976385980188'/><link rel='alternate' type='text/html' href='http://maventweaks.blogspot.com/2012/10/fun-with-git-remote-branches.html' title='Fun with git remote branches'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/17001550261994560281</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-8528942568460675966.post-6894246474044580851</id><published>2012-08-21T10:35:00.002+02:00</published><updated>2012-08-21T10:36:46.557+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="gradle"/><title type='text'>The perils of gradle wrapper and CI</title><content type='html'>If you are building yours software with Gradle, using gradle-wrapper is a great thing to ensure that your build is able to run out of the box after checking out just by running &quot;gradlew&quot; in your project directory.&lt;br /&gt;
&lt;br /&gt;
Just today I got a nice message from Hans Dockter (gradleware Germany), telling me that there have been a lot of downloads of gradle-1.0 (about 2100) in the course of one or two months, which caused some notable trafic on gradle.org.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;2100 downloads check in at about 64 GB of data.&lt;br /&gt;
&lt;br /&gt;
So, what was the cause? As we don&#39;t have an infinite number of monkeys using gradle here, the primary suspect is jenkins.&lt;br /&gt;
A good number of jobs (about 20) use Gradle for building, and each job is configured to use Gradle wrapper, because it is convenient and ensures the build runs exactly with the right Gradle version.&lt;br /&gt;
&lt;br /&gt;
So it seems like every job was happily downloading Gradle over and over again, which puts some load on gradle.org (bad)&amp;nbsp; and slows down the build (even worse).&lt;br /&gt;
&lt;br /&gt;
The solution is simple: Just installGradle centrally on your Jenkins and configure the Jenkins jobs to use the centrally provided Gradle instance. I am dong this for my jobs right now and I expect them to behave better afterwards.&lt;br /&gt;
&lt;br /&gt;
I am sure that gradle.org and the speed of your build jobs will thank you for it.</content><link rel='replies' type='application/atom+xml' href='http://maventweaks.blogspot.com/feeds/6894246474044580851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maventweaks.blogspot.com/2012/08/the-perils-of-gradle-wrapper-and-ci.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/6894246474044580851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/6894246474044580851'/><link rel='alternate' type='text/html' href='http://maventweaks.blogspot.com/2012/08/the-perils-of-gradle-wrapper-and-ci.html' title='The perils of gradle wrapper and CI'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/17001550261994560281</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-8528942568460675966.post-6023763457669829484</id><published>2010-10-19T11:48:00.003+02:00</published><updated>2010-10-19T14:36:29.589+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="maven security"/><title type='text'>Encoding your passwords in Maven</title><content type='html'>If you dislike storing your passwords in clear just like me then Maven 2.1.x or 3.x can help you out.&lt;br /&gt;
&lt;br /&gt;
At the Maven site the documentation is somwhat hidden, so I&#39;ll just describe the process in short and put up a link to the relevant documentation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;How it works&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Maven employs a two-step approach to securing your passwords.&lt;br /&gt;
&lt;br /&gt;
The first step to security is to define a master password that is stored separateley from your normal Maven settings.xml file.&lt;br /&gt;
&lt;br /&gt;
This is done by invoking Maven with the following commandline:&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;mvn -emp [master password]&lt;/pre&gt;&lt;br /&gt;
This yields an ecrypted password that looks like:&lt;br /&gt;
&lt;pre&gt;{8XfdxChqWiIHuQtHizPd+kawVIzRF1WWmsKmGUbMcLw=}&lt;/pre&gt;&lt;br /&gt;
Put the encrypted password in a file named settings-security.xml in your home folder ($HOME/.m2/settings-security.xml)&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;settingsSecurity&amp;gt;
  &amp;lt;master&amp;gt;{8XfdxChqWiIHuQtHizPd+kawVIzRF1WWmsKmGUbMcLw=}&amp;lt;/master&amp;gt;
&amp;lt;/settingsSecurity&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
After defining your master password you can simply encode your server passwords with&lt;br /&gt;
&lt;pre&gt;mvn -ep [server password]&lt;/pre&gt;and put the resulting encoded password in the &lt;tt&gt;password&lt;/tt&gt;-Tag of your &lt;tt&gt;server&lt;/tt&gt;-definitions in settings.xml.&lt;br /&gt;
&lt;br /&gt;
If you are particularly concerned about your passwords you can also store your password on removable media.&lt;br /&gt;
&lt;br /&gt;
This approach is described in detail in the Mini-HowTo at the Apache Maven site (see below for link).&lt;br /&gt;
&lt;br /&gt;
For more information have a look at the original mini HowTo: &lt;a href=&quot;http://maven.apache.org/guides/mini/guide-encryption.html&quot;&gt;http://maven.apache.org/guides/mini/guide-encryption.html&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://maventweaks.blogspot.com/feeds/6023763457669829484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maventweaks.blogspot.com/2010/10/encoding-your-passwords-in-maven.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/6023763457669829484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/6023763457669829484'/><link rel='alternate' type='text/html' href='http://maventweaks.blogspot.com/2010/10/encoding-your-passwords-in-maven.html' title='Encoding your passwords in Maven'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/17001550261994560281</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-8528942568460675966.post-4629185117312937642</id><published>2010-10-14T10:21:00.001+02:00</published><updated>2011-12-01T22:42:55.027+01:00</updated><title type='text'>Best practices for multi-module project organisation</title><content type='html'>When setting up a maven project consisting of multiple modules there are multiple ways to define the project dependencies.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Use one top level directory containing only module subfolders. The parent/module-POM resides in it&#39;s own module subdirectory (e.g. project-parent)&lt;/li&gt;
&lt;li&gt;Use one top level directory containing module subfolders&amp;nbsp; and the parent/module-POM.&lt;/li&gt;
&lt;li&gt;Use one top level directory containing module subfolders and a POM file defining the modules of the project. The parent-POM resides in a submodule folder.&lt;/li&gt;
&lt;/ol&gt;
These  are the three most common approaches to organize your project structure, each of which has it&#39;s own advantages and disadvantages.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;Approach 1&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Plus Side:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Works well with IDEs like Eclipse&lt;/li&gt;
&lt;/ul&gt;
Minus Side:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Hard to integrate with continous build systems because of the colocation of the definition of modules and the parent pom configuration. This makes standalone watchdog builds of modules almost impossible because the whole source tree is necessary to build a module.&lt;/li&gt;
&lt;/ul&gt;
&lt;b&gt;Approach 2&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Plus Side:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Only one single top level POM to maintain. &lt;/li&gt;
&lt;/ul&gt;
&amp;nbsp;Minus Side:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Hard to integrate with continous build systems because of the colocation of the definition of modules and the parent pom configuration. This makes standalone watchdog builds of modules almost impossible because the whole source tree is necessary to build a module.&lt;/li&gt;
&lt;li&gt;Top level POM is hard to integrate into project structures (e.g. eclipse) as it lies in a parent directory of the modules&#39; project definitions.&lt;/li&gt;
&lt;/ul&gt;
&lt;b&gt;Approach 3&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
Plus Side:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Parent POM is easily defineable as project in your IDE&lt;/li&gt;
&lt;li&gt;Module definitions are separated from project configuration enabling the project to have multiple module set definition, e.g. have a definition to build only a subset of all modules - for impatient developers(like myself ;-)).&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Good integration with continuous integration systems because module definitions do not interfere with standalone module builds.&lt;/li&gt;
&lt;/ul&gt;
Minus Side:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;POMs containing module definitions may be difficult to integrate in IDE.&lt;/li&gt;
&lt;/ul&gt;
&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
In my experience the third approach works best for most larger modules. Especially the compatibility with both IDEs and continuous build systems like Hudson make your work a lot easier.&lt;br /&gt;
&lt;br /&gt;
So what does the recommended structure look like? Quite simple. You simply have a main directory that contains a top-level POM file and subdirectories for the parent module and submodules.&lt;br /&gt;
&lt;br /&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/AVvXsEhjCjW0iGvr33iFwPKNi4od2l5zkWIEW9-RkoH_lktYT__fRJGonDPIKAB5bqUJ1cMYjeAjtkpGw9qW0LDBTAjmQBe__wmQWcpiNI3JS4sE2ubT4PBYf1ZSBvb3SPUkjtrKoEUt-HQcevwW/s1600/Bildschirmfoto+2011-12-01+um+22.39.30.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjCjW0iGvr33iFwPKNi4od2l5zkWIEW9-RkoH_lktYT__fRJGonDPIKAB5bqUJ1cMYjeAjtkpGw9qW0LDBTAjmQBe__wmQWcpiNI3JS4sE2ubT4PBYf1ZSBvb3SPUkjtrKoEUt-HQcevwW/s320/Bildschirmfoto+2011-12-01+um+22.39.30.png&quot; width=&quot;276&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
A sample minimal project can be downloaded from &lt;a href=&quot;https://github.com/jabbrwcky/sample-maven-structure&quot; target=&quot;_blank&quot;&gt;github&lt;/a&gt;&amp;nbsp;(I guess I could make a Maven artifact for it but I just do not have the time right now).</content><link rel='replies' type='application/atom+xml' href='http://maventweaks.blogspot.com/feeds/4629185117312937642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maventweaks.blogspot.com/2010/10/best-practices-for-multi-module-project.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/4629185117312937642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/4629185117312937642'/><link rel='alternate' type='text/html' href='http://maventweaks.blogspot.com/2010/10/best-practices-for-multi-module-project.html' title='Best practices for multi-module project organisation'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/17001550261994560281</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/AVvXsEhjCjW0iGvr33iFwPKNi4od2l5zkWIEW9-RkoH_lktYT__fRJGonDPIKAB5bqUJ1cMYjeAjtkpGw9qW0LDBTAjmQBe__wmQWcpiNI3JS4sE2ubT4PBYf1ZSBvb3SPUkjtrKoEUt-HQcevwW/s72-c/Bildschirmfoto+2011-12-01+um+22.39.30.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8528942568460675966.post-6050055851533506639</id><published>2009-09-14T14:58:00.005+02:00</published><updated>2010-10-19T14:33:01.110+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jspc"/><category scheme="http://www.blogger.com/atom/ns#" term="maven"/><category scheme="http://www.blogger.com/atom/ns#" term="multi-project"/><category scheme="http://www.blogger.com/atom/ns#" term="war"/><title type='text'>Precompiling JSPs with Maven - Part 2</title><content type='html'>If you use war dependencies for building your web applications the approach described in &lt;a href=&quot;http://maventweaks.blogspot.com/2009/09/precompiling-jsp-pages-with-maven.html&quot;&gt;part 1&lt;/a&gt;&amp;nbsp;will not work for your application because the JSPC-Plugin by default works on your local JSP files and is executed during the lifecycle phase &quot;process-classes&quot;.&lt;br /&gt;
&lt;br /&gt;
Here is how to deal with this added requirement.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Moreover if you use tag files in your JSPs (especially if the Tag pages come from the included web application) the JSP parser will fail when trying to compile the &amp;nbsp;JSP files because it needs access to the sources of all JSP pages referenced.&lt;br /&gt;
&lt;br /&gt;
The solution to this problems exploits the fact that the war plugin checks for modifications before every step it takes.&lt;br /&gt;
&lt;br /&gt;
The steps for the solution described here are acutally quite simple:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Configure an extra Execution of the WAR-Plugin to run during the lifecycle phase &quot;process-classes&quot; to exectue the goal &quot;exploded&quot;.&lt;/li&gt;
&lt;li&gt;Run the jspc plugin during the same execution but after the war plugin has run but configure it to operate on the exploded war archive.&lt;/li&gt;
&lt;li&gt;Run the war plugin again with goal &quot;war&quot; during lifecycle phase &quot;package&quot;.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;Please see the next code snippet for the solution described above:&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;plugin&amp;gt; 
  &amp;lt;groupId&amp;gt;org.codehaus.mojo.jspc&amp;lt;/groupId&amp;gt; 
  &amp;lt;artifactId&amp;gt;jspc-maven-plugin&amp;lt;/artifactId&amp;gt; 
  &amp;lt;executions&amp;gt; 
    &amp;lt;execution&amp;gt; 
      &amp;lt;id&amp;gt;precompileJsps&amp;lt;/id&amp;gt; 
      &amp;lt;goals&amp;gt; 
        &amp;lt;goal&amp;gt;compile&amp;lt;/goal&amp;gt; 
      &amp;lt;/goals&amp;gt; 
      &amp;lt;phase&amp;gt;package&amp;lt;/phase&amp;gt; 
      &amp;lt;configuration&amp;gt; 
        &amp;lt;sources&amp;gt; 
          &amp;lt;directory&amp;gt;${basedir}/target/${project.build.finalName}&amp;lt;/directory&amp;gt; 
          &amp;lt;includes&amp;gt; 
            &amp;lt;include&amp;gt;**/*.jspx&amp;lt;/include&amp;gt; 
          &amp;lt;/includes&amp;gt; 
        &amp;lt;/sources&amp;gt; 
        &amp;lt;source&amp;gt;1.5&amp;lt;/source&amp;gt; 
        &amp;lt;target&amp;gt;1.5&amp;lt;/target&amp;gt; 
        &amp;lt;verbose&amp;gt;1&amp;lt;/verbose&amp;gt; 
        &amp;lt;inputWebXml&amp;gt;${basedir}/target/${project.build.finalName}/WEB-INF/web.xml&amp;lt;/inputWebXml&amp;gt; 
      &amp;lt;/configuration&amp;gt; 
    &amp;lt;/execution&amp;gt; 
  &amp;lt;/executions&amp;gt; 
  &amp;lt;dependencies&amp;gt; 
    &amp;lt;!-- Please see Part 1 for jspc dependencies --&amp;gt;
  &amp;lt;/dependencies&amp;gt; 
&amp;lt;/plugin&amp;gt; 
&lt;/pre&gt;The configuration of the war plugin looks like this:&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;plugin&amp;gt; 
  &amp;lt;artifactId&amp;gt;maven-war-plugin&amp;lt;/artifactId&amp;gt; 
  &amp;lt;executions&amp;gt; 
    &amp;lt;execution&amp;gt; 
      &amp;lt;id&amp;gt;precompileJsps&amp;lt;/id&amp;gt; 
      &amp;lt;goals&amp;gt; 
        &amp;lt;goal&amp;gt;exploded&amp;lt;/goal&amp;gt; 
      &amp;lt;/goals&amp;gt; 
      &amp;lt;phase&amp;gt;process-classes&amp;lt;/phase&amp;gt; 
      &amp;lt;configuration&amp;gt; 
        &amp;lt;warSourceDirectory&amp;gt;${basedir}/WebContent&amp;lt;/warSourceDirectory&amp;gt; 
        &amp;lt;overlays&amp;gt; 
          &amp;lt;overlay&amp;gt; 
            &amp;lt;groupId&amp;gt;com.acme&amp;lt;/groupId&amp;gt; 
            &amp;lt;artifactId&amp;gt;base-webapp&amp;lt;/artifactId&amp;gt; 
          &amp;lt;/overlay&amp;gt; 
        &amp;lt;/overlays&amp;gt; 
      &amp;lt;/configuration&amp;gt; 
    &amp;lt;/execution&amp;gt; 
    &amp;lt;execution&amp;gt; 
      &amp;lt;goals&amp;gt; 
        &amp;lt;goal&amp;gt;war&amp;lt;/goal&amp;gt; 
      &amp;lt;/goals&amp;gt; 
      &amp;lt;configuration&amp;gt; 
        &amp;lt;warSourceDirectory&amp;gt;${basedir}/target/${project.build.finalName}&amp;lt;/warSourceDirectory&amp;gt; 
        &amp;lt;overlays&amp;gt; 
          &amp;lt;overlay&amp;gt; 
            &amp;lt;groupId&amp;gt;com.acme&amp;lt;/groupId&amp;gt; 
            &amp;lt;artifactId&amp;gt;base-webapp&amp;lt;/artifactId&amp;gt; 
          &amp;lt;/overlay&amp;gt; 
        &amp;lt;/overlays&amp;gt; 
      &amp;lt;/configuration&amp;gt; 
    &amp;lt;/execution&amp;gt; 
  &amp;lt;/executions&amp;gt; 
&amp;lt;/plugin&amp;gt; 
&lt;/pre&gt;&lt;b&gt;Important: The war plugin has to be configured before the war plugin in the POM because Maven executes the plugins within an execution in the order they are declared in the POM.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
An that&#39;s all there is to precomipling JSPs in a multi project implementation using war dependencies.</content><link rel='replies' type='application/atom+xml' href='http://maventweaks.blogspot.com/feeds/6050055851533506639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maventweaks.blogspot.com/2009/09/precompiling-jsps-with-maven-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/6050055851533506639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/6050055851533506639'/><link rel='alternate' type='text/html' href='http://maventweaks.blogspot.com/2009/09/precompiling-jsps-with-maven-part-2.html' title='Precompiling JSPs with Maven - Part 2'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/17001550261994560281</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-8528942568460675966.post-6546230672718462336</id><published>2009-09-13T22:18:00.008+02:00</published><updated>2010-10-19T14:32:10.306+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jspc"/><category scheme="http://www.blogger.com/atom/ns#" term="maven"/><category scheme="http://www.blogger.com/atom/ns#" term="war"/><title type='text'>Precompiling JSP Pages with Maven</title><content type='html'>Recently I encountered the requirement to precompile JSP pages in a Maven webapp project using the following environment:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Java 5&lt;/li&gt;
&lt;li&gt;Tomcat 5.x&lt;/li&gt;
&lt;li&gt;Jsp pages with XML Syntax (jspx)&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Solving the problem is not too difficult if you keep some things in mind.&lt;/div&gt;&lt;div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/div&gt;Precompiling JSP pages has a number of advantages (and some disadvantages too):&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The precompiled JSP pages are delivered as servlets which means that the application runs at full speed immediately after deploying it. Compiling JSP pages on demand may not matter with an application that uses a few JSP pages but it definitely matters when having 300+ JSP pages.&lt;/li&gt;
&lt;li&gt;It is possible to tweak the Java Compiler for JSP pages to use optimisations and to leave out debug informations which can speed up the application a little further.&lt;/li&gt;
&lt;li&gt;The Precompiler finds every error in every JSP (even in seldomly used pages/error pages)&lt;/li&gt;
&lt;/ol&gt;There are some disadvantages which should be remembered as well:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The used JSP compiler version has to match the container version as close as possible. So if you update your tomcat installation you need to recompile your webapp or it may fail in a worst case scenario.&lt;/li&gt;
&lt;li&gt;Turning on javac optimisations and turning off debug information makes it much harder to track down errors. So you&#39;d better have good loggin in your application to get an idea why errors happened.&lt;/li&gt;
&lt;li&gt;Not all servlet containers are supported by the used plugin. Currently it should work without problems with Jetty and Tomcat.&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;So, what is needed to include JSP precompilation in your Maven web project? &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;A recent Maven version (2+). I currently use Maven 2.2.1.&lt;/li&gt;
&lt;li&gt;The Maven JspC Plugin from codehaus (currently 2.0-alpha-3)&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;The first step is to declare the plugins and configure them as with every other maven plugin.  The jspc plugin documentation could use some improvement and updating. It took me some time to gather the required information to get it up and running. The results of this exptedition are found in the next code snippet: &lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;plugin&amp;gt;
  &amp;lt;groupid&amp;gt;org.codehaus.mojo.jspc&amp;lt;/groupid&amp;gt;
  &amp;lt;artifactid&amp;gt;jspc-maven-plugin&amp;lt;/artifactid&amp;gt;
  &amp;lt;executions&amp;gt;
    &amp;lt;execution&amp;gt;
      &amp;lt;id&amp;gt;precompileJsp&amp;lt;/id&amp;gt;
      &amp;lt;goals&amp;gt;
        &amp;lt;goal&amp;gt;compile&amp;lt;/goal&amp;gt;
      &amp;lt;goals&amp;gt;
      &amp;lt;configuration&amp;gt;
        &amp;lt;sources&amp;gt;
          &amp;lt;directory&amp;gt;${basedir}/WebContent&amp;lt;/directory&amp;gt;
          &amp;lt;includes&amp;gt;
            &amp;lt;include&amp;gt;**/*.jspx&amp;lt;/include&amp;gt;
          &amp;lt;/includes&amp;gt;
        &amp;lt;/sources&amp;gt;
        &amp;lt;source&amp;gt;&amp;lt;/source&amp;gt;1.5
        &amp;lt;target&amp;gt;1.5&amp;lt;/target&amp;gt;
      &amp;lt;/configuration&amp;gt;
    &amp;lt;execution&amp;gt;
  &amp;lt;/execution&amp;gt;
  &amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt; 
      &amp;lt;groupid&amp;gt;org.codehaus.mojo.jspc&amp;lt;/groupid&amp;gt; 
      &amp;lt;artifactid&amp;gt;jspc-compiler-tomcat5&amp;lt;/artifactid&amp;gt; 
      &amp;lt;version&amp;gt;2.0-alpha-3&amp;lt;/version&amp;gt; 
    &amp;lt;/dependency&amp;gt; 
    &amp;lt;dependency&amp;gt; 
      &amp;lt;groupid&amp;gt;org.slf4j&amp;lt;/groupid&amp;gt; 
      &amp;lt;artifactid&amp;gt;slf4j-log4j12&amp;lt;/artifactid&amp;gt; 
      &amp;lt;version&amp;gt;1.5.6&amp;lt;/version&amp;gt; 
    &amp;lt;/dependency&amp;gt; 
    &amp;lt;dependency&amp;gt; 
      &amp;lt;groupid&amp;gt;org.slf4j&amp;lt;/groupid&amp;gt; 
      &amp;lt;artifactid&amp;gt;jcl-over-slf4j&amp;lt;/artifactid&amp;gt; 
      &amp;lt;version&amp;gt;1.5.6&amp;lt;/version&amp;gt; 
    &amp;lt;/dependency&amp;gt; 
  &amp;lt;/dependencies&amp;gt;
&amp;lt;/plugin&amp;gt;&lt;/pre&gt;There are some obvious and some, well, less obvious settings to configure.&lt;br /&gt;
&amp;nbsp;The biggest pain with the jspc plugin is the incomplete declaration of&amp;nbsp; dependencies of the jsp compiler that is actuall used.&lt;br /&gt;
For some reason you have to include the slf4j jars in the dependencies or the jspc plugin refuses to work with some misleading error.&lt;br /&gt;
&lt;br /&gt;
The specific version of Tomcats JSP compiler implementation defaults to 5.5.23 for the jspc-plugin 2.0-alpha-3.&lt;br /&gt;
If you need to use another version of thew Jasper compiler, you have to declare the following dependencies for the jspc-maven-plugin: &lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;dependency&amp;gt;
  &amp;lt;groupid&amp;gt;tomcat&amp;lt;/groupid&amp;gt;
  &amp;lt;artifactid&amp;gt;jasper-compiler&amp;lt;/artifactid&amp;gt;
  &amp;lt;version&amp;gt;5.5.27&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupid&amp;gt;tomcat&amp;lt;/groupid&amp;gt;
  &amp;lt;artifactid&amp;gt;jasper-compiler-jdt&amp;lt;/artifactid&amp;gt;
  &amp;lt;version&amp;gt;5.5.27&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupid&amp;gt;tomcat&amp;lt;/groupid&amp;gt;
  &amp;lt;artifactid&amp;gt;jasper-runtime&amp;lt;/artifactid&amp;gt;
  &amp;lt;version&amp;gt;5.5.27&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
With this configuration your WAR should grow by a few bytes to a few MB. If you are using Servlet 2.4+ you do not need to change your web.xml to add the servlet mappings.&lt;br /&gt;
&lt;br /&gt;
If you are stuck with Servlet API 2.3 you&#39;ll have to paste the generated web.xml fragement into your file.&lt;br /&gt;
&lt;br /&gt;
In the next post I will extend JSP precompilation to projects using WAR dependencies, which poses some additional implications and problems.</content><link rel='replies' type='application/atom+xml' href='http://maventweaks.blogspot.com/feeds/6546230672718462336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maventweaks.blogspot.com/2009/09/precompiling-jsp-pages-with-maven.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/6546230672718462336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8528942568460675966/posts/default/6546230672718462336'/><link rel='alternate' type='text/html' href='http://maventweaks.blogspot.com/2009/09/precompiling-jsp-pages-with-maven.html' title='Precompiling JSP Pages with Maven'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/17001550261994560281</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>