But he is absolutely correct about the key observation: a basic tool with "plugins" is simply NOT the way to create a build tool. A built tool should allow (when needed) the full flexibility of a Turing complete programming language. Because eventually your project is probably going to need it.
So...the way that you do that in Maven is to create a plugin, which is very easy to do. There's your full flexibility, as soon as you want it.
Your plugin has to play by the rules, which is a good thing.
Maven's useful for more than the beginning of a project. If you're working on real-world software, you're probably not the only person who has to understand your bespoke build, if that's the way that you've chosen to go.
The problem is that there is a large overhead associated with writing a plugin. Sometimes the things you need to do are as small as copying a file from one directory or another. Having to write a plugin to do something so small is overkill.
Does this already exist? Based on the top result I get from a Google search for 'maven copy file' [1] this seems to be not very well solved. The top response in that Stack Overflow page recommends calling out to a completely different build tool. It seems like part of the problem is that frequently you will have several plugins that each solve part of a problem but it is difficult to combine the plugins so they solve the complete problem. This seems to result in a lot more 'reinventing the wheel' because something that should be easy involves a lot of hoop jumping.
The stack overflow question is about copying files to a remote server during a build, not just copying a file to a directory. Use http://maven.apache.org/plugins/maven-resources-plugin/examp... — if your build copies files to a remote server you have other problems.
As far as I can tell, that question doesn't say anything about about a remote (as in on another machine) server. It sounds like the question is just about copy files to a directory outside of the Maven project.
I know that Maven is ultimately capable of being used to copy a file. However, there are multiple ways to do this because all of the options have limitations and are somewhat awkward to use. For instance, I don't think resource plugin you linked to supports renaming as part of the copy.
Why is using your build to push files to a remote server a problem? A common use would be to deploy local code to an environment that simulates production. If that cannot be done as part of the build then it will exist as scripts that exist outside of the build. This means that there will probably be a lot more 'reinventing the wheel'.
Ah, like some of the commenters, I interpreted this line:
"I have config files and various documents that I want to copy from the dev environment to the dev-server directory using Maven2."
To mean a remote dev-server and then maven-upload was mentioned in the list of solutions. Let me step back a bit.
Maven is primarily interested in the process of building. There are functions that allow deployment but generally that is not Maven's domain. Using Maven as part of your deployment process is definitely going to be at odds with a smooth experience. I think of it like making non-default choices in Ruby on Rails, you are asking for pain.
As to your point about "reinventing the wheel" for deployment using maven, I would suggest that there are many tools designed for deployment and would use those instead, like cap.
I can understand making that interpretation at first glance.
I agree that the process of building should be the primary focus of a build tool. I also, think that the secondary purpose is to make development easier. That is why you do 'rake rails' instead of having to use cap to deploy your changes locally. It's not that hard to come across a scenario that falls in to one of these goals that requires custom logic (like copying a file, or something similar). Some of this should go in custom plugins so it can be reused. However, some of it is small and non-generic and makes no sense as a plugin. The solution you pointed to for copying a file involves substantially more code to include and configure the plugin than it would take in other JVM build tools (such as SBT or Gradle) to simply specify that you want to copy a file.
I agree that doing deployment for final builds or to shared environments are better served by a different tool.
agree fully. IF you are doing something remotely common, chances are theres already a maven plugin that does it. It might have bugs, but chances are, the plugin is also opensource, so its no worse than you writing it yourself than having to fix the bug(s) you encounter.
The only reason i don't like maven is not because of its rigidity, but because of its network dependence. To use maven, you really need to run your own repository server, and that comes with huge overheads. I m warming up to the idea of always mandating offline mode in maven, and then check in to the scm a preloaded repository which includes all the libs and plugins for your project, and never have to worry about external repos, or network connectivity.
I used to be really annoyed by that too, but I'm not any more. It's _really important_ in commercial software development to understand where your code comes from. Having a local repository act as a gatekeeper does a nice job of that. It's a good idea to always have builds run where maven settings force use of a local repository. You can then easily track everything that's going into builds, and scale that up over larger numbers of projects.
You can also push libraries into the repository that aren't open source, and know that you've done so.
Running a maven repository doesn't take much. Sonatype's basic offerings are fine and quite effective.
I think that's an interesting concern, but you might be in a different enviornment than I am.
If "network dependence" is an issue for you, you could check in your ~/.m2 directory iff you don't want to run a repository server and you're deploying to many machines that have access to source control (which you probably do if you're running maven on that machine) and you don't have access to the internet. Then it's almost like a Ant 'lib' directory type of build, but with version information, docs, and sources all available if you want it and easily refreshed when you do have network access.
I thought that, then I installed nexus and let it proxy the remote repositories and really haven't looked back. Takes some time to setup (few hours). But makes life so much easier that it's well worth the effort, especially that with Java you WILL have a dependency on a 3rd party jar from Oracle that for whatever reason won't ever show up in maven central or want to include some other 3rd party repository.
A built tool should allow (when needed) the full
flexibility of a Turing complete programming language.
Because eventually your project is probably going to need
it.
I've never seen a situation like this - but perhaps I've lived a sheltered life. Can anyone give me an example of when this would be a good design decision?
You're generating configuration files from a database as part of your build.
OR
You're reading a file and using the details in that file to control your build.
OR
You need to loop through a set of properties and apply a specific update to each value before the build.
OR
You need to invoke complex build logic based on the platform you're building for (nested ifs).
etc.
There are lots of odd situations you end up in with real projects.
The flexibility this provides comes at the cost of build complexity though.
Obscure syntax and odd custom DSL's (>_> cmake, make, powershell) are bad because they introduce complexity and destroy the readability and maintainability of the build.
You basically need a test suite for your build code to make sure it's building correctly. Terrible.
...but, necessary. I'm not a java guy, but writing C and C++? You need to do this stuff all of the time. scons or cmake really make life a lot easier than trying to force Makefiles to do things with their obscure lambda syntax.
>You basically need a test suite for your build code to make sure it's building correctly
Absolutely, which is one of the best things about maven - because all your build steps are plugins written in standard Java, you can test it the same way you test your regular code.
You should take a look at http://www.gradle.org/ if you haven't already.
I worked on an ant project and decided we needed to convert to a better build system. I started down the path of Maven, but Gradle changed my mind because of the conciseness.
It uses the groovy language so hopefully it doesn't fall into the same trap as described in the post.
Gradle has given me a lot of headaches for small projects. I keep going back to it now and then and run into performance issues with it where builds that take 10 seconds in Maven take 10 min in Gradle.
It's something about the dependency resolution mechanism. Something is broken, but I haven't been able to pin-point it yet.
It's frustrating because I love Groovy. I write a lot of Groovy and I'd love to use a Groovy-based build tool, but I can't justify wasting a lot of time on Gradle when I know how to do what I need to do in Maven.
I've used Gradle on a handful of small projects and am very surprised that you're seeing an order of magnitude difference between a Maven build and a Gradle one. Can you provide a little more detail about what the script was doing for 10 minutes?
Last time I used it which was right around when 1.3 was released I turned on debug logging while the project built so I could see what was causing the issues. It was hanging long periods of time around a task I had to make a fat jar. If I remember correctly it was having some real trouble with locks on Ivy caches... I tried clearing out the Gradle caches and that did not resolve the problem. Since that was a small project I was able to replace the build file with a POM and assembly descriptor be done with it.
If I get some more time to play around I might go back and try and collect some more info for a bug report... I have had this issue since the late Gradle betas each time I go back to using Gradle I hope the problem is resolved.
Well, 1.4 claims to have improvements to dependency resolution, so soon you should be able to take another kick at the football soon. I'm growing to like Gradle more and more and haven't seen any problems like this. My major desire is for more/better plugins, but I do think this will become less of an issue. (I'm even hoping to write 1 or 2)
I should also mention that GVMTool is worth checking out if you're on a UNIX-based system. An easy way to install and switch between versions of Gradle and other tools: http://gvmtool.net
I think developers are dogmatic and stick to a particular religion. I don't mind mind maven but I hate when I see an example piece of code and the only way to get it to work is complicated maven(pom) script. Then I have to spend a hour trying to figure out what is in the maven script. And you end up with only 2 or 3 jars (log4j and commons-logging junit and some other jar). Why don't you just give me the version I need in a bundled jar and I can go about my coding.
My only fear with maven is when things break or someone how you have a wrong version of maven that the script requires or downloads fail or something else. If the script fails you can't do anything. And who knows, the only that was required was just compiling the java source with minimal dependencies.
But he is absolutely correct about the key observation: a basic tool with "plugins" is simply NOT the way to create a build tool. A built tool should allow (when needed) the full flexibility of a Turing complete programming language. Because eventually your project is probably going to need it.