Archive

Posts Tagged ‘maven’

Stop the f… about Gradle

July 21st, 2013 15 comments

Stop the f… about #Spring & #Hibernate migrating to #Gradle. Repeat after me: “my project do NOT have the same requirements” #Maven

This was my week’s hate tweet, and I take full responsibility for every character in it. While that may seem like a troll, Twitter is not really the place to have a good-natured debate with factual arguments, so here is the follow up.

Before going into full-blown rhetoric mode, let me first say that despite popular belief, I’m open to shiny new things. For example, despite being a Vaadin believer – which is a stateful server-side technology, I’m also interested in AngularJS – which is its exact opposite. I’m also in favor of TestNG over JUnit, and so on. I even went as far as going to a Gradle session at Devoxx France! So please, hear my arguments out, only then think them over.

So far, I’ve heard only two arguments in favor of Gradle:

  1. It’s flexible (implying Maven is not)
  2. Spring and Hibernate use it

Both are facts, let’s go in detail over each of them to check why those are not arguments.

Gradle is flexible

There’s no denying that Gradle is flexible: I mean, it’s Groovy with a build DSL. Let us go further: how is flexibility achieved? My take is that it comes from the following.

  • Providing very fine-grained – almost atomic operations: compilation, copying, moving, packaging, etc.
  • Allowing to define lists of those operation – tasks: packaging a JAR would mean copying classes and resources files into a dedicated folder and zipping it
  • Enabling dependencies between those: packaging is dependent on compilation

If you look at it closely, what I said can be applied to Gradle, of course, but also to Ant! Yes, both operate at the same level of granularity.

Now the problem lies in that Gradle proponents tell Gradle is flexible as if flexibility was a desirable quality. Let me say: flexibility is not a quality for a build tool. I would even say it is a big disadvantage. That’s the same as having your broken arm put in a cast. That’s a definite lack of flexibility (to says the least) but it’s for your own good. The cast prevents you from moving in a painful way, just as unflexible build tools (such as Maven) make strange things definitely expensive.

If you need to do something odd over and over because of your specific context, it’s because of a recurring requirement. In Maven, you’d create a plugin to address it and be done with that. If it’s a one-shot requirement, that’s probably no requirement but a quirk. Rethink the way you do it, it’s a smell something is definitely fishy.

Spring and Hibernate both use Gradle

That one really makes me laugh: because some framework choose a build, we should just use theirs, no questions asked? Did you really check why they migrated in the first place?

I won’t even look at the Hibernate case, because it annoys me to no end to read arguments such as “I personally hate…” or “…define the build and directories the way that seemed to make sense to me”. That’s no good reason to change a build tool (but a real display of inflated ego in the latter case).

For Spring, well… Groovy is just in their strategic path and has been for years. SpringSource Tools Suite fully support Groovy, so I guess using Gradle is a way to spread Groovy love all over the world. A more technical reason I’ve heard is that Spring must be compatible with different Java versions, and Maven cannot address that. I’m too lazy to check for myself but even if that’s true, it has only a slight chance of applying to your current project.

Gradlew is one cool feature

The only feature I know of that I currently lack – and would definitely love to have, is to set the build engine version once and for all, to be able to run my build 10 years from now if I need it. It’s amazing the number of software products that go to their first maintenance cycle in years and are at loss building from sources. Believe me, it happened to me (in a VB environment) but I had the fortune to have a genius at hand, something I unfortunately cannot count on.

In the Gradle parlance, such feature is achieved through something known the Gradle Wrapper. Using that downloads the build engine itself, so you can put it into your version control. Too bad nobody ever raised this as an argument :-) though this is not enough to make me want to migrate.

Note: during this writing, I just searched for a port of this feature to Maven and I found maven-wrapper. Any feedback?

Wrap-up

TL;DR:

  • Gradle is just Ant with Groovy instead of XML
  • Your context is (probably) different from those of frameworks which are using Gradle

Both points have only one logical conclusion: there’s no real reason to use Gradle, stop the f… about it and go back to develop the next Google Search, there’s much more value in that!

Send to Kindle
Categories: Java Tags: , , ,

Maven between different environments

July 7th, 2013 3 comments

As a consultant, I find myself in different environments in need of different configurations. One such configuration is about the Maven settings file. This file is very important, for it governs such things as servers, mirrors and proxies. When you have a laptop, switching from customer configuration to home configuration and vice versa when you change place quickly becomes a bore. When you have to handle more than one customer, it escalates a nightmarish and tangled configuration mess.

In a former environment, colleagues handled Eclipse ini file switch, a very similar concern, by having a dedicated .bat to overwrite the reference file. I heard a colleague of mine do exactly the same for Maven settings file. It does the job, but it is not portable, is more than slightly intrusive and has something I cannot put quite my finger on that does not “fit”.

As IT people are, I’m lazy but idealist, so I scratched my head to handle this problem in a way I would deem more elegant. I think I may have found one, through Maven command native CLI. If you run mvn --help, you’ll get plenty of CLI options: go to the -s section.

 -s,--settings <arg>     Alternate path for the user
                               settings file

This means Maven let you use settings files other than ~/.m2/settings.xml. So you can create settings-cust.xml, set all needed configuration for this customer and run mvn -s ~/.m2/settings-cust.xml.

And since I’m really lazy, I just added the following snippet in my ~/.bash_profile to make my life even easier:

alias mvncust='mvn -s ~/.m2/settings-cust.xml'

Now, I just need to run mvncust to run Maven with all relevant configuration for this environment. And it is compatible with other options!

The only drawback I found so far is I’ve to explicitly set the settings file in Eclipse’s m2e but that doesn’t bother me much since I’ve a dedicated Eclipse instance (for configuration and plugins) for each of my environment.

Send to Kindle
Categories: Java Tags:

Re-use your test classes across different projects

August 25th, 2012 1 comment

Sometimes, you need to reuse your test classes across different projects. These are two use-cases that I know of:

  • Utility classes that create relevant domain objects used in different modules
  • Database test classes (ans resources) that need to be run in the persistence project as well as the integration test project

Since I’ve seen more than my share of misuses, this article aim to provide an elegant solution once and for all.

Creating the test artifact

First, we have to use Maven: I know that not everyone is a Maven fanboy, but it get the work done – and in our case, it does it easily. Then, we configure the JAR plugin to attach tests. This will compile test classes and copy test resources, and package them in an attached test artifact.

<project>
  <build>
    <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-jar-plugin</artifactId>
       <version>2.2</version>
       <executions>
         <execution>
           <goals>
             <goal>test-jar</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
    </plugins>
  </build>
</project>

The test artifact is stored side-by-side with the main artifact once deployed in the repository. Note that the configured test-jar is bound to the install goal.

Using the test artifact

The newly-created test artifact can be expressed as a dependency of a projet with the following snippet:

<dependency>
  <groupId>ch.frankel.blog.foo</groupId>
  <artifactId>foo</artifactId>
  <version>1.0.0</version>
  <type>test-jar</type>
  <scope>test</scope>
</dependency>

The type has to be test-jar instead of simply jar in order to Maven to pick the attached artifact and not the main one. Also, note although you could configure the dependency with a classifier instead of a type, the current documentation warns about possible bugs and favor the type configuration.

To go further:

Send to Kindle
Categories: Java Tags: ,

Empower your CSS in your Maven build

July 8th, 2012 No comments

People who know me also know I’ve interest in the GUI: that means I’ve sometimes to get my hands dirty and dig deep into stylesheets (even though I’ve no graphical skill whatsoever). When it happens, I’ve always questions regarding how to best factorize styles. In this regard, the different CSS versions are lacking, because they were not meant to be managed by engineers. A recent trend is to generate CSS from a source, which brings some interesting properties such as nesting, variables, mixins, inheritance and others. Two examples of this trend are LESS and SASS.

A not-so-quick example can be found just below.

Given that I’m an engineer, the only requirement I have regarding those technologies is that I can generate the final CSS during my build in an automated and reproductible way. After a quick search, I became convinced to use wro4j. Here are the reasons why, in a simple use-case.

Maven plugin

Wro4j includes a Maven plugin. In order to call it in the build, just add it to your POM:

<plugin>
	<groupId>ro.isdc.wro4j</groupId>
	<artifactId>wro4j-maven-plugin</artifactId>
	<version>1.4.6</version>
	<executions>
		<execution>
			<goals>
				<goal>run</goal>
			</goals>
			<phase>generate-resources</phase>
		</execution>
	</executions>
</plugin>

You’re allergic to Maven? No problem, a command-line tool is also provided, free of charge.

Build time generation

For evident performance reasons, I favor build time generation instead of runtime. But if you prefer the latter, there’s a JavaEE filter ready just for that.

Configurability

Since wro4j original strategy is runtime generation, default configuration files are meant to be inside the archive. However, this can easily tweaked by setting some tags in the POM:

<configuration>
	<wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
	<wroFile>${basedir}/src/main/config/wro.xml</wroFile>
	<extraConfigFile>${basedir}/src/main/config/wro.properties</extraConfigFile>
</configuration>

The final blow

The real reason to praise wro4j is that LESS generation is only a small part of its features: for wro4j, it’s only a processor among others. You’ve only to look at the long list of processors (pre- and post-) available to want to use them ASAP. For example, wro4j also wraps a JAWR processor (a bundling and minifying product I’ve blogged about some time ago).

Once you get there, however, a whole new universe opens before your eyes, since you get processors for:

  • Decreasing JavaScript files size by minifying them with Google, YUI, JAWR, etc.
  • Decreasing CSS files size by minifying them
  • Minimizing the number of requests by merging your JavaSscript files into a single file
  • Minimizing the number of requests by merging your CSS files into a single file
  • Processing LESS CSS
  • Processing SASS CSS
  • Analyzing your JavaScript with LINT

The list is virtually endless, you should really have a look. Besides, you can bridge your favorite by writing your own processor if the need be.

Quick how-to

In order to set up wro4j real quick, here are some ready to use snippets:

  • The Maven POM, as seen above
    <plugin>
    	<groupId>ro.isdc.wro4j</groupId>
    	<artifactId>wro4j-maven-plugin</artifactId>
    	<version>1.4.6</version>
    	<configuration>
    		<wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
    		<wroFile>${basedir}/src/main/config/wro.xml</wroFile>
    		<extraConfigFile>${basedir}/src/main/config/wro.properties</extraConfigFile>
    		<targetGroups>all</targetGroups>
    		<cssDestinationFolder>${project.build.directory}/${project.build.finalName}/style/</cssDestinationFolder>
    		<jsDestinationFolder>${project.build.directory}/${project.build.finalName}/script/</jsDestinationFolder>
    		<contextFolder>${basedir}/src/main/webapp/</contextFolder>
    		<ignoreMissingResources>false</ignoreMissingResources>
    	</configuration>
    	<executions>
    		<execution>
    			<goals>
    				<goal>run</goal>
    			</goals>
    			<phase>generate-resources</phase>
    		</execution>
    	</executions>
    </plugin>

    Note the use of the ConfigurableWroManagerFactory. It makes adding and removing processors a breeze by updating the following file.

  • The wro.properties processors file, that list processings that should be executed on the source files. Here, we generate CSS from LESS, resolve imports to have a single file and minify both CSS (with JAWR) and JavaScript:
    preProcessors=lessCss,cssImport
    postProcessors=cssMinJawr,jsMin
  • The wro.xml configuration file, to tell wro4j how to merge CSS and JS files. In our case, styles.css will be merged into all.css and global.js into all.js.
    <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>
    <groups xmlns=&quot;http://www.isdc.ro/wro&quot;>
      <group name=&quot;all&quot;>
        <css>/style/styles.css</css>
        <js>/script/global.js</js>
      </group>
    </groups>
  • Finally, a LESS example can be found just below.

Conclusion

There are some paths to optimization for webapps readily available. Some provide alternative ways to define your CSS, some minify your CSS, some your JS, other merge those files together, etc. It would be a shame to ignore them because they can be a real asset in heavy-load scenarii. wro4j provides an easy way to wrap all those operations into a reproductible build.

LESS
@default-font-family: Helvetica, Arial, sans-serif;

@default-radius: 8px;

@default-color: #5B83AD;
@dark-color: @default-color - #222;
@light-color: @default-color + #222;

.bottom-left-rounded-corners (@radius: @default-radius) {
	.rounded-corners(0, 0, @radius, 0)
}

.bottom-right-rounded-corners (@radius: @default-radius) {
	.rounded-corners(0, 0, 0, @radius)
}

.bottom-rounded-corners (@radius: @default-radius) {
	.rounded-corners(0, 0, @radius, @radius)
}

.top-left-rounded-corners (@radius: @default-radius) {
	.rounded-corners(@radius, 0, 0, 0)
}

.top-right-rounded-corners (@radius: @default-radius) {
	.rounded-corners(0, @radius, 0, 0)
}

.top-rounded-corners (@radius: @default-radius) {
	.rounded-corners(@radius, @radius, 0, 0)
}

.rounded-corners(@top-left: @default-radius, @top-right: @default-radius, @bottom-left: @default-radius, @bottom-right: @default-radius) {
	-moz-border-radius: @top-left @top-right @bottom-right @bottom-left;
	-webkit-border-radius: @top-left @top-right @bottom-right @bottom-left;
	border-radius: @top-left @top-right @bottom-right @bottom-left;
}

.default-border {
	border: 1px solid @dark-color;
}

.no-bottom-border {
	border-bottom: 0;
}

.no-left-border {
	border-left: 0;
}

.no-right-border {
	border-right: 0;
}

body {
	font-family: @default-font-family;
	color: @default-color;
}

h1 {
	color: @dark-color;
}

a {
	color: @dark-color;
	text-decoration: none;
	font-weight: bold;

	&amp;:hover {
		color: black;
	}
}

th {
	color: white;
	background-color: @light-color;
}

td, th {
	.default-border;
	.no-left-border;
	.no-bottom-border;
	padding: 5px;

	&amp;:last-child {
		.no-right-border;
	}
}

tr:first-child {

	th:first-child {
		.top-left-rounded-corners;
	}

	th:last-child {
		.top-right-rounded-corners;
	}

	th:only-child {
		.top-rounded-corners;
	}
}

tr:last-child {

	td:first-child {
		.bottom-left-rounded-corners;
	}

	td:last-child {
		.bottom-right-rounded-corners;
	}

	td:only-child {
		.bottom-rounded-corners;
	}
}

thead tr:first-child th, thead tr:first-child th {
	border-top: 0;
}

table {
	.rounded-corners;
	.default-border;
	border-spacing: 0;
	margin: 5px;
}
Generated CSS
.default-border {
	border: 1px solid #39618b;
}

.no-bottom-border {
	border-bottom: 0;
}

.no-left-border {
	border-left: 0;
}

.no-right-border {
	border-right: 0;
}

body {
	font-family: Helvetica, Arial, sans-serif;
	color: #5b83ad;
}

h1 {
	color: #39618b;
}

a {
	color: #39618b;
	text-decoration: none;
	font-weight: bold;
}

a:hover {
	color: black;
}

th {
	color: white;
	background-color: #7da5cf;
}

td,th {
	border: 1px solid #39618b;
	border-left: 0;
	border-bottom: 0;
	padding: 5px;
}

td:last-child,th:last-child {
	border-right: 0;
}

tr:first-child th:first-child {
	-moz-border-radius: 8px 0 0 0;
	-webkit-border-radius: 8px 0 0 0;
	border-radius: 8px 0 0 0;
}

tr:first-child th:last-child {
	-moz-border-radius: 0 8px 0 0;
	-webkit-border-radius: 0 8px 0 0;
	border-radius: 0 8px 0 0;
}

tr:first-child th:only-child {
	-moz-border-radius: 8px 8px 0 0;
	-webkit-border-radius: 8px 8px 0 0;
	border-radius: 8px 8px 0 0;
}

tr:last-child td:first-child {
	-moz-border-radius: 0 0 0 8px;
	-webkit-border-radius: 0 0 0 8px;
	border-radius: 0 0 0 8px;
}

tr:last-child td:last-child {
	-moz-border-radius: 0 0 8px 0;
	-webkit-border-radius: 0 0 8px 0;
	border-radius: 0 0 8px 0;
}

tr:last-child td:only-child {
	-moz-border-radius: 0 0 8px 8px;
	-webkit-border-radius: 0 0 8px 8px;
	border-radius: 0 0 8px 8px;
}

thead tr:first-child th,thead tr:first-child th {
	border-top: 0;
}

table {
	-moz-border-radius: 8px 8px 8px 8px;
	-webkit-border-radius: 8px 8px 8px 8px;
	border-radius: 8px 8px 8px 8px;
	border: 1px solid #39618b;
	border-spacing: 0;
	margin: 5px;
}
Send to Kindle
Categories: JavaEE Tags: ,

Why Eclipse WTP doesn’t publish libraries when using m2e

April 29th, 2012 No comments

Lately, I noticed my libraries weren’t published to Tomcat when I used a Maven project in Eclipse, even though it was standard war packaging. Since I mostly use Vaadin, I didn’t care much, I published the single vaadin-x.y.z.jar to the deployed WEB-INF/lib manually and I was done with it.

Then, I realized it happened on two different instances of Eclipse and for the writing of Develop Vaadin apps with Scala, I used 3 different libraries, so I wanted to correct the problem. At first, I blamed it on the JRebel plugin I recently installed, then I began investigating the case further and I found out that I needed a special Maven connector that was present in neither of my Eclipse instances: the WTP connector. I had installed this kind of connector back when Maven Integration was done by m2eclipse by Sonatype, but had forgotten that a while ago. Now the integration is called m2e, but I have to do the whole nine yards again…

The diagnostics that can be hard but the solution is very simple.

Go to the Windows -> Preferences menu and from this point on go to Maven -> Discovery.

Click on Open Catalog.

Search for “wtp”, select Maven Integration for WTP and click on Finish. Restart and be pleased. Notice that most Maven plugins integration in Eclipse can be resolved the same way.

For a sum up on my thoughts about the current state of m2e, please see here.

Send to Kindle
Categories: JavaEE Tags: , ,

Apache Maven 3 Cookbook

November 13th, 2011 No comments

This review is about Apache Maven 3 Cookbook from Srirangan from Packt Publishing.

Facts

  1. 9 chapters, 208 pages, $35.99
  2. This book covers Apache Maven 3

Pros

Each recipe is structured in 3 steps:

  1. “Getting ready”
  2. “How to do it”
  3. “See also” for references on associated recipes

Cons

  1. The scope of the book is too large for only 200 pages. It spans from Java to Scala and Groovy through Android, GWT and Flex.
  2. Most products installation processes (Sonatype Nexus, Hudson) are documented with a few screenshots. It would have been better to reference the product installation on the Web or to go in detail. In the current state of thing, most readers are left wondering what to do with it.
  3. The recipe structure is well adapted for… recipes. When talking about general Maven principles like compiling a project, it feels convoluted and artificial.
  4. Writing a whole chapter about native Maven reporting when there’s Sonar? Come on…

Conclusion

I was expecting much from this book, because I’m a daily Maven user and because Maven is regularly misused (see here and here for a start). I’m sorry to say I’m disappointed: there’s not much regarding how to resolve daily Maven problems provided. The concept is a good idea but IMHO the result is a failure.

Disclaimer: I was provided the book freely, courtesy of Packt Publishing

Send to Kindle
Categories: Book review Tags: ,

Maven doesn’t suck, your POM does

October 9th, 2011 2 comments

Maven bashing is an all-time favorite: there are plenty of articles telling how Maven downloads the whole Internet, or how POMs are bloated and so on.

While I agree that Maven could be perfected, I’m also aware that some (if not most) of its shortcomings are not intrinsic but are caused by (very) bad configuration. Worse, even if used correctly in your projects, problems sometimes come from third-party dependencies! You do not believe me? Well, two examples follow, from standard libraries.

Log4J

Coming from the classic logging framework, this may seem a surprise but log4j POM is a mess. Just look at its dependencies section:

<dependencies>
  <dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4</version>
  </dependency>
  <dependency>
    <groupId>javax.jms</groupId>
    <artifactId>jms</artifactId>
    <version>1.1</version>
  </dependency>
  ...
</dependencies>

Interestingly enough, Log4J depends on the Java Mail and JMS API! If you are using your application in an application server, you may be in for a rude surprise as conflicts may arise between your dependencies and the libraries available on the server.

Moreover, while some users may have the need of mail or JMS appenders, this is not the case for all of us. As such, there’s clearly a lack of appropriate modularization in the design of the library. Luckily, the above POM is an excerpt of version 1.2.15. Version 1.2.16 uses the optional tag for those libraries (which breaks transitivity): it addresses our application server use-case but is still a problem for those needing the dependencies as they have to add the dependency manually. See here for a thought or two on optional dependencies.

If we need version 1.2.15, there are basically two solutions.

  • Clean but cumbersome: we have to manually exclude JMS and Mail from each POM using Log4J. Who said software development was fun?
  • Gruesome but effective: if we have a Maven enterprise repository, we correct the POM (i.e. we add optional tags) on the repository.

Jasper reports

The Log4J example was straightforward: just the side-effects of bad modularization. Jasper’s POM has another twist, just look at a typical dependency:

<dependency>
  <groupId>com.lowagie</groupId>
  <artifactId>itext</artifactId>
  <version>[1.02b,)</version>
  <scope>compile</scope>
</dependency>

The version part means the dependency’s version should be between 1.02b included and the latest version. This obviously has two drawbacks:

  • From an architectural point of view, how can the POM provider guarantee there won’t be an API break with the latest version?
  • From a Maven POV, it means Maven will try to download the latest version. In order to do that, it will try to contact repo1… You’re beginning to see the problem? If you’re behing a corporate proxy that isolates you from the Internet, you’re toast.

The POM excerpt comes from version 2.0.4. Starting from version 2.0.5, Jasper’s designers used only single version dependencies.

If you’re stuck with older versions, the only solution here is to replace the POM with a manually crafted one that do not use unboundedversion dependencies on your enterprise repository.

Conclusion

Despite the constant noise on the Internet, Maven is a wonderful tool. Yet, even if I take the utmost care to design my POM, some external dependencies make my life harder. It would be better to stop losing time complaining about the tool and invest this time helping the developers of those dependencies to provide better POMs.

Send to Kindle
Categories: Java Tags:

Free eBook: Apache Maven 3 Cookbook

October 4th, 2011 No comments

Dear readers,

In order to celebrate the release of Apache Maven 3 Cookbook, Packt Publishing contacted me in order to hold a contest to grab a free copy of the eBook!

To be frank, I haven’t a clue toward organizing a contest so the first three who send me a mail at nicolas at frankel dot ch with the subject “Apache Maven 3 Cookbook” will be sent the eBook for free. Don’t waste your time: on your mark, ready, go!

And thanks Packt for these gifts.

Update[10h20]: Sorry folks, all three eBooks have already been given. Winners will be contacted shortly by a Packt representative. Thanks for participating!

Send to Kindle
Categories: Book review Tags:

Migrating from m2eclipse to m2e

September 25th, 2011 5 comments

Since Indigo, the Maven Ecliple plugin formerly known as m2eclipse became part of Eclipse release (at least in the pure Java release). The name of the plugin also changed from m2eclipse to m2e. This was not the sole change, however:

  • The number of tabs on the POM has shrinked drastically, and the features as well. This will probably be the subject of a later post since I feel quite cheated by the upgrade.
  • The POM configuration has been more integrated with Eclipse build (which can cause unwanted side-effects as I described in my last article).

More importantly, projects that began with m2eclipse can be built in Indigo but no contextual Maven menu is accessible on the project itself (though a contextual menu is available on the POM).

In order to migrate flawlessly and have our contextual menu back, some actions are necessary. They are gruesome because it involves updating by hand Eclipse configuration file.

Warning: at this point, you have the choice to stop reading. If you decide to continue and use the process described below, it’s at your own risk!

The Maven plugin recognizes a project as a Maven one based the .project Eclipse proprietary configuration file. To display it, go to the Project Explorer view, click on the scrolling menu at the top right and choose Customize View. You have to uncheck *.resources: along the .project file , you should see a .classpath file as well as a .settings folder.

  1. In the .project:
    • Replace org.maven.ide.eclipse.maven2Builder by org.eclipse.m2e.core.maven2Builder in the buildSpec section
    • Replace org.maven.ide.eclipse.maven2Nature by org.eclipse.m2e.core.maven2Nature in the natures section
  2. In the .classpath, replace org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER by org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER
  3. Finally, in the .settings folder, rename the org.maven.ide.eclipse.prefs file to org.eclipse.m2e.core.prefs. Contents should be left unchanged.

Now, the contextual menu should appear and work accordingly.

Remember, this is a big hack you should only use with the right parachute (at least a source control management system) since it will hurt you plenty if it fails. For me, it has always worked… yet.

Send to Kindle
Categories: Java Tags: , ,

Better Maven integration leads to unforeseen consequences (bugs)

September 11th, 2011 7 comments

This week, I was faced with what seemed an near-insuperable problem. I was called by one of my dev: as soon as he upgraded his Eclipse (or more precisely, our own already-configured Eclipse), he couldn’t deploy to Tomcat through WTP. Here are the steps I took to resolve the problem and more general thoughts about upgrading and tooling.

The log displayed a ClassNotFoundException, one involving Spring. So, the first step is to look under the hood. Provided you used the default configuration – to use workspace metadata – it should be located under <WORKSPACE>/.metadata/.plugins/org.eclipse.wst.server.core/tmp<i>/wtpwebapps where WORKSPACE is your workspace location and i is an incremental number beginning with 0 assigned by Eclipse to each virtual application server in WTP. There you should see the applications deployed in Eclipse. When I checked, I realized the application was deployed alright, but found no WEB-INF/lib folder.

I had already experienced such deployment problems: I solved them by first forcing publish (right-click on the server and choose Publish) and if not successful, cleaning (it removes all deployment and starts again from scratch). Well, this didn’t work.

Also, sometimes classes are not deployed because there aren’t there in the first place: compilation doesn’t occur (because of bad code or Eclipse may be playful) and this prevents generating .class files. This didn’t seem like the problem but hell, this was a lead like any other. In order to force compilation, clean the project and check recompile afterwards (or check auto build is on). This didn’t work too…

It happened before that closing the project and reopening it resolved some code-unrelated compilation problems. Closing and restarting Eclipse may yield the same results. I did both to no avail. At this point, I was disappointed because all previous steps should have resolved the problem… yet they hadn’t.

Since the project used Maven (and we had m2eclipse installed), I also checked the Maven Dependencies library was correctly referenced: it was. Just to be sure, I disabled and re-enabled dependencies management. Guess what? Nothing changed.

Desperate, I hopelessly browsed through the POM and the following caught my attention:

<plugin>
 <artifactId>maven-war-plugin</artifactId>
 <configuration>
 <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
 </configuration>
</plugin>

This configuration creates skinny WARs so that libraries are not packaged in the WAR but are in the EAR, provided they are referenced, of course (for the right way to create such WARs, see my post from last week). With a faint gleam of hope, I removed the configuration part and it worked, the libraries were finally deployed.

Yes, dear readers, it seems newer versions of the m2eclipse plugin are able to parse some portions of the POM that were not parsed before and act accordingly. Although this is a good news in general, it means we have to carefully check about potential side-effects of upgrading to those newer versions. Of course, this was stupid to upgrade in the first place but think that sometimes it’s mandatory for a newer project.

However, the problem is much more widespread than m2eclipse. It’s very similar to issues adressed in Andrew Spencer’s post, only more so since if we don’t upgrade, we may have to keep an Eclipse instance for each project, that has to be shared between all team members. Right now, I don’t have any solutions for this problem, apart from changing the code to keep in synch with the tool.

PS : since we still wanted to have skinny WARs, I just moved the configuration part in a profile… which was what was configured in the archetype provided by the support team :-)

Send to Kindle
Categories: JavaEE Tags: ,