Maven directory structure - java

I'm new to Maven and I've been reading all morning tutorials (amazing tool).
This new Java project I started looking at however doesn't use the default directory structure. Instead of src/main/java for sources it uses something like src/org/myapp.
When I run mvn package on the project (where pom.xml is located) I get a message saying that no Sources have been compiled because it's not able to find them (the source path being different).
Is there a way to specify your own sources path in Maven?

Add sourceDirectory to the build tag in the pom file.
<build>
...
<sourceDirectory>src</sourceDirectory>
...
</build>
Here is the relevant section in the maven docs.

In theory, you can use a non-standard directory structure for your Maven project. In practice, you may find that various Maven plugins and IDE integrations won't work properly. So I'd advise that you reorganize your project directory structure to be what Maven expects ... before you get lots of version control history and other stuff that will make reorganization more painful.

How did you create the project? The idea way to create a new maven project is: mvn archetype:create and then follow the instructions.
Read this for more details
Update to extend by answer based on the URL:
mvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id]

Related

Maven project version interpolation from a property file

We are using a Maven for a while in our project and want to automate the release process little bit. we came up with the following idea so that the version will be maintained by developers or in SCM instead of in DevOps tool like jenkins/bamboo.
Anyone following below process instead of setting the interpolation value in arguments as "mvn install -Dapp.version=1.0.0-SNAPSHOPT"
The process we like to follow is to supply the Maven project version through an external property file.
let's assume the following partial POM.xml excerpt as example.
<project>
<groupId>com.home.diary</groupId>
<artifactId>journal</artifactId>
<version>${app.version}</version>
<packaging>war</packaging>
</project>
let's assume i have an version.properties file in my SCM with following content
app.version=2.0.0-RELEASE
while running the mvn goal
mvn install
i want the artifact generated as
journal-2.0.0-RELEASE
I tried using plugin properties-maven-plugin from org.codehaus.mojo
as discussed here How to read an external properties file in Maven
but it's not working.
Anyone did this? could you please share your implementation/ideas?
This is not possible.
First of all: Why not just manage the version in the <version> tag itself? It is the easiest thing and fulfils your requirement (the developer manages the version in the SCM).
If you don't want this, you need to supply the version either in the POM itself or through the command line. Reading external properties with something like the properties maven plugin will always happen too late, i.e. after the version tag is already read.

Build Maven project with local dependencies

I downloaded old project, which based on Eclipse, Ant or something else, I don't know this build system (I use Maven\Gradle). Project sources was converted to Maven manually, but project had more jar libraries. They were imported in project with help of IDEA (Project Structure -> Modules -> Dependencies), but libraries defined only in .iml file.
When I tried to build project in .jar with help of Maven — Maven show errors, that it cannot find classes from libraries (but in sources all good). I found in Internet example, like in this code sample:
<dependency>
<groupId>example</groupId>
<artifactId>example</artifactId>
<version>examle</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/example.jar</systemPath>
</dependency>
But this don't help. Libraries are old too, and they created by old build tools, which don't write artifact id, group id and etc., so I don't know this information.
How I can write dependencies on local .jar libraries in pom.xml if I don't know information (group, artifact ids) about they?
UPD_0:
When I try to set only system path to library, I take this:
All you need is set correct path in the
<systemPath>${project.basedir}/libs/example.jar</systemPath>
group, artifact ids and version are user defined information. So you can define it as you wish.
Try to install this jar in ur local repository from command line / terminal like this. Then add the dependency with the package and version given by you in the command without scope as system
mvn install:install-file -Dfile=<path>/example.jar
-DgroupId=com.something
-DartifactId=example
-Dversion=<give some version>
-Dpackaging=jar
-DgeneratePom=true

Maven: Using a project folder as a repository for lib

I have a project with the following layout:
My goal was to have mvn looking in the project lib dir as an additional location for potential libs that would not be found in maven repository like j-text-utils.jar for example. So I added this in the pom.xml
<repositories>
<repository>
<id>lib</id>
<url>file://${project.basedir}/lib</url>
</repository>
</repositories>
I took the idea from here: http://randomizedsort.blogspot.co.il/2011/10/configuring-maven-to-use-local-library.html
When running mvn compile, it fails to find the relevant libs in the project folder.
Is there anything wrong with the above?
Thx
There is nothing wrong to setup a file based repository. But first and foremost, your directory structure needs to conform to the groupid/artifactid. You should use
set localrepopath=C:\path_to_repo_rootdir
call mvn install:install-file -Dfile=xyz-1.2.jar -DgroupId=com.foo -DartifactId=xyz -Dversion=1.2 -Dpackaging=jar -DlocalRepositoryPath=%localrepopath% -DcreateChecksum=true
It will create directory com\foo\1.2 with all the pom.xml, jar files, checksum files under it.
Then you need to define the dependency for these newly installed artifacts in your own project pom.xml.
If you do not want to setup local repository and only want to add them to the compile classpath, you can consider using "system" scope dependency, but it will make your build not portable and is discouraged in general.
You can do that (just configure the maven-dependency-plugin properly), but I wouldn't suggest that.
There might be a few drawbacks with that direction (e.g., having the Jars there could get into the repository you're using, for many projects it's better to have only one Jar in a dedicated place of your HDD rather than having one of them in each and every project, etc.).

How to use Maven in my Java Project and Why?

I am trying to figure out the use of Maven and I got many articles describing its features and uses. But I am just not able to understand the actual use of Maven from productivity standpoint.
From what I am used to in our school projects was just create a new Java project in Eclipse, write your Code, create a .war (if web-based) and paste the code to the webapps folder of Tomcat and start the server!
So,
Where does Maven come into picture? I have used Ant and I understand Ants benefit of a standardized build process. But why do we need an advanced Ant in form of Maven?
In any case, I need to use it, so where do I get started - basic flow, some good tutorials?
Thanks
Maven is used to manage the build, testing, and deployment processes. It can separate the unit tests and integration tests so you only run them when necessary and cut down on build time.
It is also a dependency manager, which means when you realize the server piece of your project needs apache commons-logging 1.0.4 but the client conflicts with anything past 0.7.9, you can just add a couple lines to the respective pom.xml files, and Maven handles all of that (downloading, installing, and keeping track of the different versions of those dependencies).
I was not a believer before my current task, but after 2 years using it for large enterprise applications, I definitely respect what Maven brings to the table. There are a lot of online resources but if you are going to be the lead on this and really feel uncomfortable, I recommend getting a book -- the O'Reilly one is helpful.
Forgot to mention that there is an Eclipse plugin which makes it almost painless to use with Eclipse: m2Eclipse.
Second update for example pom.xml segment to answer OP question:
Your pom.xml will contain XML code such as:
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
These are downloaded from the central Maven repository (google "maven nexus") or you can configure your own additional repositories (like for your own projects, or if you are not Internet-connected).
I had exactly the same perception as you and for years I avoided Maven.
The thing is, it allows you to easily get the required jars your application may need( called dependencies - jars and other things - ) . So the next time somebody else run your project he will get the jars automatically.
I know that's a bit hard to grasp, until you work with an existing projects using it.
For instance I downloaded an open source project recently, which depended on 10 or 12 different on different jar versions. After downloading the source code and executing Maven, all those jars ( and a lot more others ) were downloaded for me.
The problem with Maven ( as a friend of mine told me ) is that to perform a "Hello world" program, it first downloads the world to greet him. :P
for all those wondering where the maven downloads the dependency jars, check out a folder named .m2 in the user root directory. eg. for me it is the c:\documentsand settings\myUserName.m2\
also i have researched a bit on maven and i have made some small scribbling like reminders. If it is worth a read then here it is ::
/*
mvn generate
mvn install downloads all necessary jars
mvn test tests the application made...
mvn site builds the site downloading dependencies
to deploy the site, we need to declare a location to distribute to in your pom.xml,
similar to the repository for deployment.
...
website
scp://www.mycompany.com/www/docs/project/
...
mvn site-deploy deploys the site
how to build structure of site :
The site.xml file is used to describe the layout of the site, and replaces the navigation.xml file used in Maven
A sample is given below:
Maven
http://maven.apache.org/images/apache-maven-project.png
http://maven.apache.org/
http://maven.apache.org/images/maven-small.gif
<menu name="Maven 2.0">
<item name="Introduction" href="index.html"/>
<item name="Download" href="download.html"/>
<item name="Release Notes" href="release-notes.html" />
<item name="General Information" href="about.html"/>
<item name="For Maven 1.x Users" href="maven1.html"/>
<item name="Road Map" href="roadmap.html" />
</menu>
<menu ref="reports"/>
...
so in effect, we need to link our html to this structure format to make the website layout
also in order for us to add any new css or such stuff, all we need to do is to put them into the resources part of the
src folder
then we can create a war file of our project and lay it out in the httpd folder of apache or such similar folder ofour web server
In case we need to generate projects, we need to add a few lines of code to our pom.xml file and that is:
...
org.apache.maven.plugins
maven-project-info-reports-plugin
2.0.1
...
also, site descriptors are to be set in site.xml
the details can be seen in the documentation of maven
maven structure with their importance:
project/
pom.xml - Defines the project
src/
main/
java/ - Contains all java code that will go in your final artifact.
See maven-compiler-plugin for details
scala/ - Contains all scala code that will go in your final artifact. ////not needed for our current project as of yet
See maven-scala-plugin for details
resources/ - Contains all static files that should be available on the classpath
in the final artifact. See maven-resources-plugin for details
webapp/ - Contains all content for a web application (jsps, css, images, etc.)
See maven-war-plugin for details
site/ - Contains all apt or xdoc files used to create a project website.
See maven-site-plugin for details
test/
java/ - Contains all java code used for testing.
See maven-compiler-plugin for details
scala/ - Contains all scala code used for testing.
See maven-scala-plugin for details
resources/ - Contains all static content that should be available on the
classpath during testing. See maven-resources-plugin for details
mvn validate this will validate that all the dependencies are satisfied and nothing is missing
mvn compile this will compile the project
mvn verify checks whether the package is valid or not
also in the project, the dependencies are to be inserted into the xml file
the example of dependencies injection is given below::
org.scala-lang
scala-library
2.7.2-rc2
junit
junit
3.8.1
test
Each dependency consists of several items:
* groupId - The group of the dependency to rely on
* artifactId - The artifact in the group to rely on
* version - The version of the dependency to rely on
* scope - The "scope" of the dependency. Defaults to compile (more details later)
* packaging - The packaging for the dependency. Defaults to jar (e.g. jar, war, ear)
You can integrate your static pages by following these steps:
* Put your static pages in the resources directory, ${basedir}/src/site/resources
* Create your site.xml and put it in ${basedir}/src/site
* Link to the static pages by modifying the menu section, create items and map them to the filenames of the static pages
mvn tomcat:deploy to deploy to tomcat or apache, you can go for this command
Free books about Maven can be downloaded from Sonatype (where the original developers of Maven come from).
Also see the documentation on the Apache Maven website.
Where does Maven come into picture? I
have used Ant and I understand Ants
benefit of a standardized build
process. But why do we need an
advanced Ant in form of Maven?
Maven introduced "convention over configuration" this helps if some colleagues write bigger ant scipts than code. plus dependency management, the only trouble is to convert monolithic projects with many artifacts.
In any case, I need to use it, so
where do I get started - basic flow,
some good tutorials?
I found these tutorials
And Maven: The Definitive Guide
helpful.
The latest netbeans also has a pretty good maven integration.
If you are within an organization, try to build a maven repository proxy. Artifactory is a good option.

Help me understand making maven project w/ non-maven jar dependencies usable by others

I'm in the process of learning maven (and java packaging & distribution) with a new oss project I'm making as practice. Here's my situation, all java of course:
My main project is ProjectA, maven-based in a github repository. I have also created one utility project, maven-based, in github: ProjectB. ProjectA depends on a project I have heavily modified that originally was from a google-code ant-based repository, ProjectC.
So, how do I set up the build for ProjectA such that someone can download ProjectA.jar and use it without needing to install jars for ProjectB and ProjectC, and also how do I set up the build such that someone could check out ProjectA and run only 'mvn package' for a full compile?
(Additionally, what should I do with my modified version of ProjectC? include the class files directly into ProjectA, or fork the project into something that could then be used by as a maven dependency?)
I've been reading around, links such as this SO question and this SO question, but I'm unclear how those relate to my particular circumstance. So, any help would be appreciated. Thanks!
So, how do I set up the build for ProjectA such that someone can download ProjectA.jar and use it without needing to install jars for ProjectB and ProjectC
Assuming ProjectA is a JAR, you can create an executable JAR that bundles the dependencies with the Maven Assembly Plugin (and the predefined jar-with-dependencies descriptor) or with the Maven Shade Plugin.
how do I set up the build such that someone could check out ProjectA and run only 'mvn package' for a full compile?
You have to deploy the dependencies to a repository that can be read over HTTP and to declare this repository in your pom.xml. AFAIK, git-hub doesn't offer any facility for that. But any web hosting service with FTP access (or better, scp) should do the trick. If your project is open source, another option would be to use Sonatype's OSS Repository Hosting service.
Just in case, you might want to read this blog post but you won't learn much more things.
The easiest would still be to organize the 3 projects as a multi-modules maven project and to build all modules.
Additionally, what should I do with my modified version of ProjectC?
From a modularization point of view (assuming you found a solution for the above part about repository), it would certainly make sense to have it as a separate module, especially if there is an opportunity someone can use ProjectC outside your project.
You have to publish the code from the additional dependencies. Two options:
Use the maven-shade-plugin to create a maven artifact containing all the content of the B and C jars, and publish that under your own G/A/V coordinates.
Publish copies of B and C under your own G/A/V coordinates using the maven-deploy-plugin to your forge just as you will publish your own code. Different forges have different policies; but if you abide by the licenses of B and C you should be OK.

Categories