Introduction
Let's say that after a lot of research, trial and errors, you set up a base maven project with a combination of frameworks and a bunch of tricky configurations. Your project works now, it prints
Wouldn't be easier if you could incorporate this customized project to a maven catalog so you can instantiate it from the terminal with a
Maven can take a project folder and generate the maven archetype file (a jar) that can be later installed on a maven proxy/repository to be available for all the people that have access to it. This is what this tutorial is about.
"Hello World!"
in the browser window, text file or terminal, and you feel proud of yourself for being able to set up the whole thing. Now that you have this small code base, you can make a copy of the project folder and rename it as template-xyzw-project
so if you (or any other programmer) wish to start a new project, you copy this template-xyzw-project
folder, rename it and apply the appropiated tweaks. Lot of work, right?
mvn archetype:generate
command instead of copy/paste/adjust everything?
Example Project
pom.xml
that lists all the dependencies, you can also use a project of your own if you prefer.
Generate the base-archetype
cd
into the project directory (or, in the case of a multi-module project, cd
into the parent/aggregator project) and run the following command:
$ mvn archetype:create-from-projectThis will generate a bulk of files and folders under the
target/generated-sources/archetype
directory:
.
├── src
│ ├── main
│ │ └── resources
│ │ ├── archetype-resources
│ │ │ └── src
│ │ │ └── main
│ │ │ ├── java
│ │ │ │ ├── portlets
│ │ │ │ └── services
│ │ │ │ └── impl
│ │ │ └── webapp
│ │ │ ├── VAADIN
│ │ │ │ ├── themes
│ │ │ │ │ └── test-portlet
│ │ │ │ └── widgetsets
│ │ │ └── WEB-INF
│ │ │ └── spring-conf
│ │ └── META-INF
│ │ └── maven
│ └── test
│ └── resources
│ └── projects
│ └── basic
└── target
├── classes
│ ├── archetype-resources
│ │ └── src
│ │ └── main
│ │ ├── java
│ │ │ ├── portlets
│ │ │ └── services
│ │ │ └── impl
│ │ └── webapp
│ │ ├── VAADIN
│ │ │ ├── themes
│ │ │ │ └── test-portlet
│ │ │ └── widgetsets
│ │ └── WEB-INF
│ │ └── spring-conf
│ └── META-INF
│ └── maven
└── test-classes
└── projects
└── basic
From this folder structure you can discard the target
directory sub-tree (the red one), just mvn clean
it.
com.test.portlets
to com.organization.application.portlets
and adjust all the package references (updating all the xml, properties, etc files). That's the next step.
Adjusting the archetype
cd target/resources/archetype
) or you can make a copy in another directory of the archetype
folder and cd
into it, the second option is preferred as if you screw some configuration file, you can start over making another copy from the original archetype
folder, it's up to you.
pom.xml
in the archetype directory, it describes the project as a maven archetype (yes, the archetype
folder is indeed a maven project), you can change the groupId
, artifactId
and version
properties used to address the project in the GAV way, modify these properties to change the archetype name.
archetype-metadata.xml
located under the src/main/resources/META-INF/maven
directory. This file groups the resources as file sets (fileSets
) that are going to be filtered by the archetype during the generation process, every file set is of the form:
-
filtered="true"
indicates that the resource files of the file set should be parsed. Maven will use Apache Velocity templating framework to substitute/replace/conditional replace values in your files. -
packaged="true"
From the documentation: "flags maven that the resource files have to be packaged, which means the selected files will be generated/copied in a directory structure that is prepended by the package property. They can be non-packaged, which means that the selected files will be generated/copied without that prepend." -
encoding="UTF-8"
indicates that your files are in the specified encoding.
archetype-metadata.xml
should look something like this:
You have to manually add the file sets that aren't listed in the above xml, normally you wouldn't have to do that, but this project employs some files that maven thinks shouldn't be fitlered and it groups them in a non-filtered file set. Sometimes you have to delete some of this maven generated file sets, like those that group IDE files (e.g,. .settings
, .project
, etc) that you forgot to manually delete from the project folder prior to running mvn archetype:create-from-project
.
.scss
located inside the folder VAADIN/themes/test-portlet
.
-
For README and README.md, you only have to change the lines 27-34 in the above
archetype-metadata.xml
to: Open those README files and add the following lines at the beginning of the file (if they are not already there):#set( $symbol_pound = '#' ) #set( $symbol_dollar = '$' ) #set( $symbol_escape = '\' )
Every file that you want to be filtered by maven has to start with those lines, even the.java
files, but don't worry, maven archetype plugin have done this for you with all the file-sets that are initially listed in thearchetype-metadata.xml
file, so you only add those that doesn't appear in a filtered file set (or in any file set at all). Then add the value${rootArtifactId}
whenever you want the supplied user project name to appear.#set( $symbol_pound = '#' ) #set( $symbol_dollar = '$' ) #set( $symbol_escape = '\' ) README for module ${artifactId} =============================== This module belongs to the project ${rootArtifactId}
-
For the
.scss
files, first remove the.scss
include from the unfiltered file set: Now include the.scss
files in a new file set: As done above, open the.scss
files and add the#set
lines, then replace those values that contains the project name (test-portlet
) with${rootArtifactId}
, for example, open the filestyles.scss
: Then replacetest-portlet
with${rootArtifactId}
: Remember to check the java source files, and adjust those variables, methods, commets, etc that depends on the supplied project name, substitute them with${rootArtifactId}
. Note that you can even tweak the code comments to reflect the user application name. Repeat the process with all the files you want to include and filter.com.test.portlets
with the user supplied package name using the${package}
variable. There are another variables you can use:Variable Meaning ${rootArtifactId}
Already explained above, it holds the value entered by the user as the project name (the value that maven ask as the artifactId:
in the prompt when the user runs the archetype)${artifactId}
If your project is composed by one module, this variable will have the same value as ${rootArtifactId}
, but if the project contains several modules, this variable will be replaced by the module name inside every module folder, for example: given a module namedportlet-domain
inside a project namedportlet
, all the files inside this module folder that are to be filtered will have the value of the variable${artifactId}
replaced byportlet-domain
whereas the${rootArtifactId}
variable will be replaced byportlet
${package}
The user provided package for the project, also prompted by maven when the user runs the archetype ${packageInPathFormat}
The same value as ${package}
variable but replacing'.'
with the character'/'
, e.g:, for the packagecom.foo.bar
this variable iscom/foo/bar
${groupId}
The user supplied groupId
for the project, prompted by maven when the user runs the archetype${version}
The user supplied version
for the project, prompted by maven when the user runs the archetype
__rootArtifactId__
. For example, rename the VAADIN/themes/test-portlet/test-portlet.scss
to VAADIN/themes/test-portlet/__rootArtifactId__.scss
, so it will be renamed as the user supplied project name with the extension .scss
. Again, repeat this process with all those files and/or folders that you want to rename to reflect the user's project name.
Further tweaking
com/your-company/your-application-name
?
Wouldn't be even nicer if some of the web.xml
values reference your application name instead of the test-portlet
inherated from the template?
package
in the file set, it will copy the src folder content and paste it under a folder that represents the user provided project package name.
Creating the archetype (again)
cd
in the parent archetype and run:
$ mvn installThis will re-generate the
target
folder and the test-vaadin7-portlet-archetype-1.0.0-SNAPSHOT
jar file, if you want to change the archetype project (thus, change the name of the jar name), remember to edit the archetype pom.xml
file groupId
and artifactId
properties.
Test your archetype locally
mvn install
line executed in the previous section will generate a file archetype-catalog.xml
in your ~/.m2
directory with the following content:
Then, type:
$ mvn archetype:generateYour newly deployed archetype will be listed as the last one of a list that will appear in your terminal, choose the archetype, fill in the parameters and hit enter, open up your file browser and check that all the generated files accomodates to the supplied parameters.
Uploading your archetype to your local maven proxy
maven-archetype
for Packaging. Upload the archetype jar generated in the target
folder and click the button "Upload Artifact(s)", after this, the archetype should be available for all the user that have access the the proxy.
Multi-module projects
application-persist
subproject, the web application that serves as the application front-end can be in a application-webapp
subproject, and so on. All these submodules would be controlled by an Aggregator Project.
The project layout should be in hierarchical form, the parent/aggregator project must contain the module subprojects directories inside it. If you start from a flat layout structure and run mvn archetype:create-from-project
, maven will generate the module archetype rosource folders in the directory /src/main/resources
, then in the archetype creation (mvn install
) it will complain that it can't find the archetype resource files inside the folder /src/main/resources/archetype-resources
and will exit the execution with an error message. To solve this problem you have to manually move the module archetype resources to the /src/main/resources/archetype-resources
directory or rearrange your project structure to the hierarchical form.
Is usually the case that the project modules are named <project-name>-module-name
and reside inside the parent folder named <project-name>
. For example, given a project named nextgeo
with the modules persist
, web-services
and web-app
, a common project folder names for this modules would be: nextgeo-persist
, nextgeo-web-services
and nextgeo-web-app
all inside the nextgeo
folder. To process a project layout such as this, run mvn archetype:create-from-project
inside the project parent folder, then rename the subfolders nextgeo-persist
, nextgeo-web-services
and nextgeo-web-app
(inside the src/main/resources/archetype-resources
folder) to: __rootArtifactId__-persist
, __rootArtifactId__-web-services
and __rootArtifactId__-web-app
, also in the archetype-metadata.xml
you would see that the file-sets are grouped together by a <modules>
tag:
Change the base project name (nextgeo
) with the variable ${rootArtifactId}
, except for the dir
attribute that points to a folder name (this must remain equal to the phisycal folder name or maven won't be able to copy/filter the folder and its content), like this:
Everything else in the process stays the same, after you finish editing your files, run mvn install
and it should work as well as before, now your user can make an instance of the archetype by running mvn archetype:generate
. It the user provides, for example, the project name wumpus
(rootArtifactId = wumpus
), the generated folders should be: wumpus-persist
, wumpus-web-services
and wumpus-web-app
, all inside the wumpus
parent folder.
Summarized process
cd
in the project folder.- Run
mvn archetype:create-from-project
. cd
in the<project-folder>/target/generated-sources/archetype
.- Make a copy of the archetype folder (Optional).
- Delete the
target
subfolder (Optional). - Change the archetype
groupId
,artifactId
,version
anddescription
for your archetype in thepom.xml
. - Edit the file
<archetype-folder>/src/main/resources/META-INF/maven/archetype-metadata.xml
, add the file-sets you consider neccesary, edit the existing ones, remember that the attributefiltered="true"
will filter the files in the file-set replacing variables like${rootArtifactId}
with the project name given by the user in the form of theartifactId
that maven ask him/her during generation (that moment when the users uses your archetype). Also remember thatpackaged="true"
will copy the files in the file-set in a destination folder that matches the package given by the user during generation. - Edit the files you want to be specially processed, remember whenever you see the project name (your project name) replace it with the
${rootArtifactId}
variable. - Rename those files/folders that you want reflect the user provided project name during generation with
__rootArtifactId__
. - If your project is a multi-module project, then rename the modules folders using
__rootArtifactId__
inside the name (only if the module folder name contains a reference to the project name), and update thearchetype-metadata.xml
module
tags accordingly. Remember that${rootArtifactId}
will contain the project name whereas${artifactId}
will contain the module name. - Run
mvn install
from the archetype folder. - Test it using
mvn archetype:generate
, search for the last entry in the list.
Nice article!
ReplyDeleteThanks!
DeleteSorry for the late reply.
After step 11, you should run mvn archetype:update-local-catalog in folder where your archetype resides. Archetype plugin reads archetype catalogs. Google about it.
ReplyDeleteThanks for the suggestion and sorry for the late reply.
DeleteVery useful article!!!
ReplyDeleteThank you very much!!!
You're welcome, glad it was of help! And sorry for taking so long to answer the comment.
DeleteThank you for this simple and straightforward overview of the archetype creation process.
ReplyDeleteYou're welcome :)
DeleteSorry for the late reply.
+1 Thank you for this tutorial.
ReplyDeleteYou're welcome, glad it helped, sorry for the late reply.
DeleteI have a xml file it's path is src/main/resources/archetype-resources/src/main/resources/sql/myapp/DemoUser.xml.when execute mvn archetype:generate I specify artifactId is foo.bar and package is com.foo.bar(-DartifactId=foo.bar -Dpackage=com.foo.bar) but I want to DemoUser.xml in folder sql/bar/DemoUser.xml, how to implement this? That is replace myapp to bar.
ReplyDeleteWhat about renaming your folder to `src/main/resources/archetype-resources/src/main/resources/sql/__artifactId__/DemoUser.xml` and then specify the artifactId as bar and the groupId as com.foo?
DeleteHope it helps.
Thanks! I resolved it by this way: in `archetype-resources/pom.xml` I resolved app name from artifactId. #set ($artifactId = "${artifactId}")
Delete#set ($index = $artifactId.indexOf('.'))
#set ($index = $index + 1)
#set ($appName = $artifactId.substring($index)). Then in archetype-metadata.xml I add appName property and default value:
${appName}
. It seems you must put velocity syntax in pom.xml, if you put in archetype-metadata.xml it cannot be resolved.
hi I have a question of how to specify a default package value so user do not need specify a package parameter explicitly? please see http://stackoverflow.com/questions/38419903/when-execute-maven-archetype-generate-how-to-specify-a-default-package-value-cor
ReplyDeleteHello , I have a question, what if you want a json file to be filtered? because if you add the lines
ReplyDelete#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
then it will become an invalid json file. Thank you!
why when put the command mvn archetype:generate and then put the number of an archetype give this error:
ReplyDelete[ERROR] ResourceManager : unable to find resource 'archetype-resources/pom.xml' in any resource loader. ????
Hi
ReplyDeleteAm trying to create the new archetype as per your tutorial , but i do not want the .java files to include , in my instance of the module structure created based on the new archetype , can you please help me how to do this
This comment has been removed by the author.
ReplyDeleteHello, I got a question:
ReplyDeleteHow can I control that generate or not a file by a required property?
e.g:
if (prop.use.redis == true) {
generateFile("src/main/resources/redis.xml");
}
else {
System.out.println("do not need generate redis.xml");
}
This comment has been removed by the author.
ReplyDeleteHi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Java developer learn from Java Training in Chennai. or learn thru Java Online Training in India . Nowadays Java has tons of job opportunities on various vertical industry.
ReplyDeleteor Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.
This is my first time visit to your blog and I am very interested in the articles that you serve. Provide enough knowledge for me. Thank you for sharing useful and don't forget, keep sharing useful info: Visit Office Rental Singapore
ReplyDeleteRead all the information that i've given in above article. It'll give u the whole idea about it.
ReplyDeleteBest Devops Training in pune
Microsoft azure training in Bangalore
Power bi training in Chennai
This is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me..
ReplyDeleteBest Devops training in sholinganallur
Devops training in velachery
Devops training in annanagar
Devops training in tambaram
This comment has been removed by the author.
ReplyDelete
ReplyDeleteIt seems you are so busy in last month. The detail you shared about your work and it is really impressive that's why i am waiting for your post because i get the new ideas over here and you really write so well.
Selenium training in Chennai
From your discussion I have understood that which will be better for me and which is easy to use. Really, I have liked your brilliant discussion. I will comThis is great helping material for every one visitor. You have done a great responsible person. i want to say thanks owner of this blog.
ReplyDeletePython Online certification training
python Training institute in Chennai
Python training institute in Bangalore
Very interesting to read thanks
ReplyDeleteBest salesforce training in chennai
Very Clear Explanation. Thank you to share this
ReplyDeleteCCNA Course in Chennai
CCNA Training in chennai
I am obliged to you for sharing this piece of information here and updating us with your resourceful guidance. Hope this might benefit many learners. Keep sharing this gainful articles and continue updating for us.
ReplyDeleteoneplus mobile service centre in chennai
oneplus mobile service centre
oneplus service center near me
Your very own commitment to getting the message throughout came to be rather powerful and have consistently enabled employees just like me to arrive at their desired goals.
ReplyDeleteAnd indeed, I’m just always astounded concerning the remarkable things served by you. Some four facts on this page are undeniably the most effective I’ve had.
MATLAB TRAINING IN CHENNAI | Best MATLAB TRAINING Institute IN CHENNAI
EMBEDDED SYSTEMS TRAINING IN CHENNAI |Best EMBEDDED TRAINING Institute IN CHENNAI
MCSA / MCSE TRAINING IN CHENNAI |Best MCSE TRAINING Institute IN CHENNAI
CCNA TRAINING IN CHENNAI | Best CCNA TRAINING Institute IN CHENNAI
ANDROID TRAINING IN CHENNAI |Best ANDROID TRAINING Institute IN CHENNAI
Flying Shift - Packers & Movers in Bhopal
ReplyDeleteWow it is really wonderful and awesome thus it is veWow, it is really wonderful and awesome thus it is very much useful for me to understand many concepts and helped me a lot.
ReplyDeleteoracle dba training in bangalore
oracle dba courses in bangalore
oracle dba classes in bangalore
oracle dba training institute in bangalore
oracle dba course syllabus
best oracle dba training
oracle dba training centers
This is the exact information I am been searching for, Thanks for sharing the required infos with the clear update and required points. To appreciate this I like to share some useful information.
ReplyDeleteperl training institutes in bangalore
perl training in bangalore
best perl training institutes in bangalore
perl training course content
perl training interview questions
perl training & placement in bangalore
perl training center in bangalore
It is very good and useful for students and developer.Learned a lot of new things from your post Good creation,thanks for give a good information at sap crm.
ReplyDeletemysql dba training in bangalore
mysql dba courses in bangalore
mysql dba classes in bangalore
mysql dba training institute in bangalore
mysql dba course syllabus
best mysql dba training
mysql dba training centers
I have to voice my passion for your kindness giving support to those people that should have guidance on this important matter.
ReplyDeletepega training institutes in bangalore
pega training in bangalore
best pega training institutes in bangalore
pega training course content
pega training interview questions
pega training & placement in bangalore
pega training center in bangalore
Excellent post for the people who really need information for this technology.
ReplyDeletesql server dba training in bangalore
sql server dba courses in bangalore
sql server dba classes in bangalore
sql server dba training institute in bangalore
sql server dba course syllabus
best sql server dba training
sql server dba course syllabus
best sql server dba training
sql server dba training centers
I just loved your article on the beginners guide to starting a blog.If somebody take this blog article seriously in their life, he/she can earn his living by doing blogging.thank you for thizs article. pega online training , best pega online training ,
ReplyDeletetop pega online training
Excellent Blogs,Appreciating for this intense work and keep doing more...Learn Python to get a enormous impact in your life
ReplyDeletepython training in chennai | python training in annanagar | python training in omr | python training in porur | python training in tambaram | python training in velachery
Such a great word which you use in your article and article is amazing knowledge. thank you for sharing it.
ReplyDeleteDevOps Training | Certification in Chennai | DevOps Training | Certification in anna nagar | DevOps Training | Certification in omr | DevOps Training | Certification in porur | DevOps Training | Certification in tambaram | DevOps Training | Certification in velachery
Excellent Blogs,Appreciating for this intense work and keep doing more...Learn Python to get a enormous impact in your life
ReplyDeleteAWS training in Chennai
AWS Online Training in Chennai
AWS training in Bangalore
AWS training in Hyderabad
AWS training in Coimbatore
AWS training
I like your post. Everyone should do read this blog.
ReplyDeletePerl training in bangalore
very interesting stuff.thanks for sharing.Angular training in Chennai
ReplyDeleteThanks for sharing such a helpful, and understandable blog. I really enjoyed reading it.
ReplyDeleteRobots for kids
Robotic Online Classes
Robotics School Projects
Programming Courses Malaysia
Coding courses
Coding Academy
coding robots for kids
Coding classes for kids
Coding For Kids
seo fiyatları
ReplyDeletesaç ekimi
dedektör
instagram takipçi satın al
ankara evden eve nakliyat
fantezi iç giyim
sosyal medya yönetimi
mobil ödeme bozdurma
kripto para nasıl alınır
bitcoin nasıl alınır
ReplyDeletetiktok jeton hilesi
youtube abone satın al
gate io güvenilir mi
referans kimliği nedir
tiktok takipçi satın al
bitcoin nasıl alınır
mobil ödeme bozdurma
mobil ödeme bozdurma
perde modelleri
ReplyDeletesms onay
MOBİL ÖDEME BOZDURMA
Nft Nasıl Alınır
Ankara Evden Eve Nakliyat
trafik sigortası
dedektör
web sitesi kurma
aşk kitapları