I have a Maven2 project, with a pom.xml and a profiles.xml files at the same level.
The project configuration is provided by Maven profile properties:
dbhost=${dbhost}
dbport=${dbport}
// etc.
Locally, each developper customize his build in the "profiles.xml". It works well.
For continuous integration, a ci "profiles.xml" has been put on our SCM server (at the same level as the pom.xml).
The problem is that Hudson simply ignores this file during the Maven build, whereas the "-P hudsonprofile" is correctly set.
If the same profile is moved directly in the "pom.xml", or in the global "settings.xml" the build works. So we already have a solution.
I also know that the "profiles.xml" file is deprecated, but I would like to understand why the comportement is different between Hudson build and my local build...
Note: Hudson and my local build use the same version of Maven (2.2.1).
Sounds like a classpath problem to me. Why would Hudson not notice the profiles.xml? The only reason I can think of is that Hudson uses a different classpath than you would expect.
A best practice (atleast in my experience), is to try to build the project from the command line on your CI server (where Hudson runs). If that works, then Hudson should work too. Unless you have configured Maven in Hudson weirdly.
Also, adjusting the settings.xml of Maven is not that bad. At least, if you dont expect it to change too much. Even so, it is fixed quickly.
I think the best solution is defining the profiles directly in your pom.xml file for both CI specifically and then generically for local builds. Then the devs can override any profile settings in their own personal settings.xml file for local builds. This has the added benefit of not having to check-in a profiles.xml file which will not work for devs, forcing them to modify this versioned file and remember to not check in their changes. This also has the added benefit on making your build not dependent on a deprecated feature of Maven. After all, I would not count on the behavior of a deprecated feature in the first place. Hopefully this is an elegant solution which uses ideas from what you know already works.
Related
The solution which needs bootstrapping is supplied as java code. Absolutely sure that this is necessary.
Receivers of the solution are guaranteed to have a suitable JDK
However, receivers of the solution are unable to install Maven (they don't know how to and cannot be taught)
My idea is to include some sort of Maven with the project, such that can be set up in a script like so:
set up maven repo as a folder under the solution folder (using relative reference)
set up anything else maven needs (don't know what, exactly)
call /path/to/maven/mvn compile -f /path/to/oneAndOnly/pom.xml
java /target/MySolutionClas
I am aware of: https://dzone.com/articles/embedding-maven but it gets confusing when he talks about configuring the portable maven into the pom.xml - wait, how is that pom.xml going to mean anything if maven is not configured yet?
(PS: I mean no disrespect to the author. I probably got it all wrong)
One could include a shell script that would setup maven if it is not already present.
The same for building and packaging encapsulating the complexities of the setup to just runing a couple of scripts.
Maven Wrapper aims to do just that, similar to the gradle wrapper seen in many gradle projects.
Running the wrapper goal of the maven wrapper plugin will generate a mvnw script in your project that can be run in place of a globally installed mvn command.
It's part of the maven 3.7.0 release, and documented more fully here: https://maven.apache.org/plugins/maven-wrapper-plugin/index.html
See https://github.com/takari/maven-wrapper for maven < 3.7.0
Simple console maven artifacts with shared dependencies (some also provide public API's in addition to their own class) living on same production server. How to best organise/install on production server?
My instinct is for a single folder holding all (version numbered) jars (ie. a 'flattened'/dependency populated 'repository') however:
(a) Can't see how such a folder would increase, on a 'dependency' basis, it's population from maven deployment repository
(b) How a jar's manifest's classpath would change from the default 'lib/...,lib/...' (ie. relative to 'main' jar, sensible for dev/test using Eclipse) to just '...,...'
What is recommended best practice as regards organisation on production server?
Google'ing 'maven production classpath' (amongst others) resulted in http://blog.armstrongconsulting.com/?p=232 which seems related but light on detail.
Any pointers?
How experienced are you with Maven? If you are the process described in the blog you mention is pretty straightforward also without going into details.
Re (a): Dependencies are downloaded from a remote Maven repository into a local Maven repository on demand. Default in ${user.home}/.m2/repository or according to <localRepository> at the beginning of your settings.xml. See Introduction to Repositories. So, there's no need for a single 'flattened'/dependency populated 'repository' folder.
A local repository can also be populated with the install:install-file goal manually. But this can be a cumbersome process if there are many artifacts to install.
See Maven, Available Plugins for what the mentioned plugin:goals do.
I am new to using github and have been trying to figure out this question by looking at other people's repositories, but I cannot figure it out. When people fork/clone repositories in github to their local computers to develop on the project, is it expected that the cloned project is complete (ie. it has all of the files that it needs to run properly). For example, if I were to use a third-party library in the form of a .jar file, should I include that .jar file in the repository so that my code is ready to run when someone clones it, or is it better to just make a note that you are using such-and-such third-party libraries and the user will need to download those libraries elsewhere before they begin work. I am just trying to figure at the best practices for my code commits.
Thanks!
Basically it is as Chris said.
You should use a build system that has a package manager. This way you specify which dependencies you need and it downloads them automatically. Personally I have worked with maven and ant. So, here is my experience:
Apache Maven:
First word about maven, it is not a package manager. It is a build system. It just includes a package manager, because for java folks downloading the dependencies is part of the build process.
Maven comes with a nice set of defaults. This means you just use the archtype plugin to create a project ("mvn archetype:create" on the cli). Think of an archetype as a template for your project. You can choose what ever archetype suits your needs best. In case you use some framework, there is probably an archetype for it. Otherwise the simple-project archetype will be your choice. Afterwards your code goes to src/main/java, your test cases go to src/test/java and "mvn install" will build everything. Dependencies can be added to the pom in maven's dependency format. http://search.maven.org/ is the place to look for dependencies. If you find it there, you can simply copy the xml snippet to your pom.xml (which has been created by maven's archetype system for you).
In my experience, maven is the fastest way to get a project with dependencies and test execution set up. Also I never experienced that a maven build which worked on my machine failed somewhere else (except for computers which had year-old java versions). The charm is that maven's default lifecycle (or build cycle) covers all your needs. Also there are a lot of plugins for almost everything. However, you have a big problem if you want to do something that is not covered by maven's lifecycle. However, I only ever encountered that in mixed-language projects. As soon as you need anything but java, you're screwed.
Apache Ivy:
I've only ever used it together with Apache Ant. However, Ivy is a package manager, ant provides a build system. Ivy is integrated into ant as a plugin. While maven usually works out of the box, Ant requires you to write your build file manually. This allows for greater flexibility than maven, but comes with the prize of yet another file to write and maintain. Basically Ant files are as complicated as any source code, which means you should comment and document them. Otherwise you will not be able to maintain your build process later on.
Ivy itself is as easy as maven's dependency system. You have an xml file which defines your dependencies. As for maven, you can find the appropriate xml snippets on maven central http://search.maven.org/.
As a summary, I recommend Maven in case you have a simple Java Project. Ant is for cases where you need to do something special in your build.
I'm building a Java project that has a dependency on a library. mvn.bat clean install produced the target subdirectories as expected, and the project built fine with mvn.bat clean install as well.
What's not expected is that when I deleted the entire directory of the library, the outer project still built fine, although the library it depends on was gone.
How does this work?
UPDATE: Turns out Maven makes some sort of cache in %USERPROFILE\.m2.
You are most likely thinking of your local repository where everything you install locally (and maven downloads for you from the central repository) is put for later usage.
The behavior you describe is intentional, and allows for building A once and then let B reference it whenever needed, without having to recompile A every time. This is usually very desirable, especially in teams or with large code bases.
Note, that for changing code you should be using -SNAPSHOT artifacts. They are treated slightly differently.
Your dependencies are always downloaded into .m2/repository.
If you want to have some predictability on downloaded libraries in your team, you can put in place a repository manager like Nexus : https://repository.apache.org/index.html#welcome
Instead of downloading dependencies from Maven central, your developers will download their dependencies from this repository manager.
I'm new to Maven, using the m2e plugin for Eclipse. I'm still wrapping my head around Maven, but it seems like whenever I need to import a new library, like java.util.List, now I have to manually go through the hassle of finding the right repository for the jar and adding it to the dependencies in the POM. This seems like a major hassle, especially since some jars can't be found in public repositories, so they have to be uploaded into the local repository.
Am I missing something about Maven in Eclipse? Is there a way to automatically update the POM when Eclipse automatically imports a new library?
I'm trying to understand how using Maven saves time/effort...
You picked a bad example. Portions of the actual Java Library that come with the Java Standard Runtime are there regardless of Maven configuration.
With that in mind, if you wanted to add something external, say Log4j, then you would need to add a project dependency on Log4j. Maven would then take the dependency information and create a "signature" to search for, first in the local cache, and then in the external repositories.
Such a signature might look like
groupId:artifactId:version
or perhaps
groupId:artifactId:version:classifier
This identifies a maven "module" which will then be downloaded and configured into your system. Once in place it adds all of the classes within the module to your configured project.
Maven principally saves time in downloading and organizing JAR files in your build. By defining a "standard" project layout and a "standard" build order, Maven eliminates a lot of the guesswork in the "why isn't my project building" sweepstakes. Also, you can use neat commands like "mvn dependency:tree" to print out a list of all the JARs your project depends on, recursively.
Warning note: If you are using the M2E plugin and Eclipse, you may also run into problems with the plugin itself. The 1.0 version (hosted at eclipse.org) was much less friendly than the previous 0.12 version (hosted at Sonatype). You can get around this to some extent by downloading and installing the "standalone" version of Maven from apache (maven.apache.org) and running Maven from the command line. This is actually much more stable than trying to run Maven inside Eclipse (in my personal experience) and may save you some pain as you try to learn about Maven.