Maven用仓库外的jar进行编译
http://blog.csdn.net/zhouysh/article/details/5713532
?
之所以采用Maven調(diào)用ant 進(jìn)行編譯,是因?yàn)橛幸恍﹍ib 并不在遠(yuǎn)程倉庫里,而是直接放到project/lib目錄下。
?
編譯的時(shí)候要依賴這些lib包, maven里好像沒什么辦法把這些非倉庫里的lib包加入到classpath中來,才采用調(diào)用ant的方式。
?
ps: 但是如果要采用這種把非倉庫lib的加入到classpath的方式,就無法使用maven官方推薦的maven-ant-tasks進(jìn)行抽取pom的dependency,所以我在這個(gè)例子中把那段注釋掉了。。
這是不是一個(gè)maven的bug?
?
?
?
----------------------------------------------------------------------------
Pom.xml:
?
<build>
?<plugins>
??<plugin>
???<groupId>org.apache.maven.plugins</groupId>
???<artifactId>maven-antrun-plugin</artifactId>
???<version>1.3</version>
???<executions>
????<execution>
?????<id>ant-build</id>
?????<phase>generate-sources</phase>
?????<goals>
??????<goal>run</goal>
?????</goals>
?????<configuration>
??????<tasks>
???????<property name="compile_classpath" refid="maven.compile.classpath" />
???????<property name="runtime_classpath" refid="maven.runtime.classpath" />
???????<property name="test_classpath" refid="maven.test.classpath" />
???????<property name="plugin_classpath" refid="maven.plugin.classpath" />
???????<property name="artifactId" value="${project.artifactId}" />?
???????<property name="version" value="${project.version}" />
???????<property name="build.compiler" value="extJavac"/>??????????????? ????????
???????<ant antfile="build.xml" />
??????</tasks>
?????</configuration>
????</execution>
???</executions>
??</plugin>
?</plugins>
</build>
?
-------------------------------------------------------------------------------------------------------------------
build.xml
?
<project name="uslaminstallerjavaproject" default="dist" basedir="." xmlns:artifact="urn:maven-artifact-ant">
?<property environment="env" />
?<property name="vendor" value="HP Company." />
?<property name="work.src" value="${basedir}/src/main/java" />
?<property name="work.conf" value="${basedir}/src/main/resources" />
?<property name="work.lib" value="${basedir}/lib" />
?<property name="work.dist" value="${basedir}/target" />
?<property name="work.classes" value="${basedir}/target/classes" />
?<echo message="compile classpath: ${compile_classpath}" />
?<echo message="runtime classpath: ${runtime_classpath}" />
?<echo message="test classpath:??? ${test_classpath}" />
?<echo message="plugin classpath:? ${plugin_classpath}" />
?
?<target name="clean" description="Delete old build and dist directories">
??<echo message=" Clean the classe directory" />
??<delete dir="${work.classes}" />
??<delete dir="${work.dist}" />
?</target>
?<target name="mkdir" description="Make build and dist directories">
??<echo message=" Make the classe directory" />
??<mkdir dir="${work.classes}" />
??<mkdir dir="${work.dist}" />
?</target>
?
<!--?但是如果要采用這種把非倉庫lib的加入到classpath的方式,就無法使用maven官方推薦的maven-ant-tasks進(jìn)行抓取dependency -->
?<!--
?<target name="maven-jar" description="Use Maven2 to manage jars' dependencies">
??<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant">
???<classpath>
????<pathelement location="lib/maven-ant-tasks-2.0.9.jar" />
???</classpath>
??</typedef>
??<artifact:pom id="maven.project" file="pom.xml"? />
??<echo message="The build directory is ${maven.project.build.directory}" />
??<artifact:dependencies pathId="maven.classpath" filesetId="maven.deps.fileset" usescope="runtime">
???<pom refid="maven.project" />
??</artifact:dependencies>
?</target>
?-->
?<path id="project.classpath">
??<dirset dir="${work.conf}"/>
??<fileset dir="${work.lib}">
???<include name="**/*.jar"/>
???<include name="**/*.zip"/>
??</fileset>
??<pathelement path="${compile_classpath}"/>
??<!--<fileset refid="maven.deps.fileset" /> -->
?</path>
?<target name="compile" description="compiles all source files">
??<echo message=" Start to compile..." />
??<javac srcdir="${work.src}" destdir="${work.classes}" debug="true">
???<classpath refid="project.classpath" />
??</javac>
??<echo message=" Finish to compile..." />
?</target>
?<target name="jar-all" description="Jar the classes">
??<jar destfile="${work.dist}/${artifactId}-${version}.jar"?
???????????? basedir="${work.classes}" encoding="UTF-8">
???<fileset dir="${work.conf}">
????<include name="**/*.*"/>
???</fileset>
?
???<manifest>
????<attribute name="Implementation-Title"?
???????????????????? value="${artifactId}" />
????<attribute name="Implementation-Version"?
???????????????????? value="${version}" />
????<attribute name="Implementation-Vendor"?
???????????????????? value="${vendor}" />
???</manifest>
??</jar>
?</target>
?
?<target name ="zip-release" description="Zip the final release file">
??? <zip destfile="${work.dist}/${artifactId}-${version}.zip">
????? <zipfileset dir="${work.dist}" includes="**/*.jar"/>
????? <zipfileset dir="${work.lib}" includes="**/*.jar" excludes= "maven-ant-tasks*.jar" />
??? </zip>
?</target>
?<target name="dist" depends="clean,mkdir,compile,jar-all">
??<antcall target="zip-release">
??</antcall>
?</target>
</project>
?
?
========================
另外一種就是在父項(xiàng)目中調(diào)用兩個(gè)子模塊,第一個(gè)模塊去將jar安裝到本地倉庫,第二個(gè)子模塊就可以依賴這些jar了
?
==========
?
<dependency>
???<groupId>xxx</groupId>
???<artifactId>xxx</artifactId>
???<version>1.0</version>
???<scope>system</scope>
???<systemPath>${basedir}/src/main/lib/xxx.jar</systemPath>
?</dependency>
在eclipse項(xiàng)目需右鍵選擇Maven->enable dependency management
http://stackoverflow.com/questions/364114/can-i-add-jars-to-maven-2-build-classpath-without-installing-them
Can I add jars to maven 2 build classpath without installing them?
| up vote 239 down vote favorite 134 | Maven2 is driving me crazy during the experimentation/quick and dirty mock-up phase of development. I have a pom.xml file that defines the dependencies for the web-app framework I want to use, and I can quickly generate starter projects from that file. However, sometimes I want to link to a 3rd party library that doesn't already have a pom.xml file defined, so rather than create the pom.xml file for the 3rd party lib by hand and install it, and add the dependency to my pom.xml, I would just like to tell maven: "In addition to my defined dependencies, include any jars that are in /lib too." It seems like this ought to be simple, but if it is, I am missing something. Any pointers on how to do this are greatly appreciated. Short of that, if there is a simple way to point maven to a /lib directory and easily create a pom.xml with all the enclosed jars mapped to a single dependency which I could then name/install and link to in one fell swoop would also suffice. Thanks! javamaven-2 | ||
| ? |
|
15 Answers
activeoldest votes| up vote 217 down vote | set scope == system and just make up a groupId, artifactId, and version <dependency><groupId>org.swinglabs</groupId><artifactId>swingx</artifactId><version>0.9.2</version><scope>system</scope><systemPath>${project.basedir}/lib/swingx-0.9.3.jar</systemPath> </dependency> | ||||||||||||||||||||
| ? |
|
| up vote 133 down vote | Problems of popular approachesMost of the answers you'll find around the internet will suggest you to either install the dependency to your local repository or specify a "system" scope in thepom and distribute the dependency with the source of your project. But both of these solutions are actually flawed. Why you shouldn't apply the "Install to Local Repo" approachWhen you install a dependency to your local repository it remains there. Your distribution artifact will do fine as long as it has access to this repository. The problem is in most cases this repository will reside on your local machine, so there'll be no way to resolve this dependency on any other machine. Clearly making your artifact depend on a specific machine is not a way to handle things. Otherwise this dependency will have to be locally installed on every machine working with that project which is not any better. Why you shouldn't apply the "System Scope" approachThe jars you depend on with the "System Scope" approach neither get installed to any repository or attached to your target packages. That's why your distribution package won't have a way to resolve that dependency when used. That I believe was the reason why the use of system scope even got deprecated. Anyway you don't want to rely on a deprecated feature. The static in-project repository solutionAfter putting this in your pom: <repository><id>repo</id><releases><enabled>true</enabled><checksumPolicy>ignore</checksumPolicy></releases><snapshots><enabled>false</enabled></snapshots><url>file://${project.basedir}/repo</url> </repository>for each artifact with a group id of form x.y.z Maven will include the following location inside your project dir in its search for artifacts: repo/ | - x/ | | - y/ | | | - z/ | | | | - ${artifactId}/ | | | | | - ${version}/ | | | | | | - ${artifactId}-${version}.jarTo elaborate more on this you can read this blog post. Use Maven to install to project repoInstead of creating this structure by hand I recommend to use a Maven plugin to install your jars as artifacts. So, to install an artifact to an in-project repository underrepo folder execute: mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]If you'll choose this approach you'll be able to simplify the repository declaration inpom to: <repository><id>repo</id><url>file://${project.basedir}/repo</url> </repository>A helper scriptSince executing installation command for each lib is kinda annoying and definitely error prone, I've created autility script which automatically installs all the jars from alib folder to a project repository, while automatically resolving all metadata (groupId, artifactId and etc.) from names of files. The script also prints out the dependencies xml for you to copy-paste in yourpom. Include the dependencies in your target packageWhen you'll have your in-project repository created you'll have solved a problem of distributing the dependencies of the project with its source, but since then your project's target artifact will depend on non-published jars, so when you'll install it to a repository it will have unresolvable dependencies. To beat this problem I suggest to include these dependencies in your target package. This you can do with either theAssembly Plugin or better with theOneJar Plugin. The official documentaion on OneJar is easy to grasp. | ||||||||||||||
| ? |
|
| up vote 24 down vote | Note: When using the System scope (as mentioned on this page), Maven needs absolute paths. If your jars are under your project's root, you'll want to prefix your systemPath values with ${basedir}. |
| ? | feedba |
| up vote 9 down vote | You really ought to get a framework in place via a repository and identifying your dependencies up front. Using the system scope is a common mistake people use, because they "don't care about the dependency management." The trouble is that doing this you end up with a perverted maven build that will not show maven in a normal condition. You would be better off following an approach likethis. | ||
| ? |
|
| up vote 6 down vote | Maven install plugin has command line usage to install a jar into the local repository, POM is optional but you will have to specify the GroupId, ArtifactId, Version and Packaging (all the POM stuff). | ||||
| ? |
|
| up vote 5 down vote | This is what I have done, it also works around the package issue and it works with checked out code. I created a new folder in the project in my case I used repo, but feel free to usesrc/repo In my POM I had a dependency that is not in any public maven repositories <dependency><groupId>com.dovetail</groupId><artifactId>zoslog4j</artifactId><version>1.0.1</version><scope>runtime</scope> </dependency>I then created the following directories repo/com/dovetail/zoslog4j/1.0.1 and copied the JAR file into that folder. I created the following POM file to represent the downloaded file (this step is optional, but it removes a WARNING) and helps the next guy figure out where I got the file to begin with. <?xml version="1.0" encoding="UTF-8" ?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.dovetail</groupId><artifactId>zoslog4j</artifactId><packaging>jar</packaging><version>1.0.1</version><name>z/OS Log4J Appenders</name><url>http://dovetail.com/downloads/misc/index.html</url><description>Apache Log4j Appender for z/OS Logstreams, files, etc.</description> </project>Two optional files I create are the SHA1 checksums for the POM and the JAR to remove the missing checksum warnings. shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar \> repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar.sha1shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom \> repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom.sha1Finally I add the following fragment to my pom.xml that allows me to refer to the local repository <repositories><repository><id>project</id><url>file:///${basedir}/repo</url></repository> </repositories> | ||||||
| ? |
|
| up vote 3 down vote | The problem with systemPath is that the dependencies' jars won't get distributed along your artifacts as transitive dependencies. Try what I've posted here:Is it best to Mavenize your project jar files or put them in WEB-INF/lib? Then declare dependencies as usual. And please read the footer note. | ||
| ? |
|
| up vote 3 down vote | This is how we add or install a local jar <dependency><groupId>org.example</groupId><artifactId>iamajar</artifactId><version>1.0</version><scope>system</scope><systemPath>${project.basedir}/lib/iamajar.jar</systemPath></dependency>i gave some default groupId and artifactId because they are mandatory :) | ||
| ? |
|
| up vote 2 down vote | If you want a quick and dirty solution, you can do the following (though I do not recommend this for anything except test projects, maven will complain in length that this is not proper). Add a dependency entry for each jar file you need, preferably with a perl script or something similar and copy/paste that into your pom file. #! /usr/bin/perlforeach my $n (@ARGV) {$n=~s@.*/@@;print "<dependency><groupId>local.dummy</groupId><artifactId>$n</artifactId><version>0.0.1</version><scope>system</scope><systemPath>\${project.basedir}/lib/$n</systemPath> </dependency> "; | ||
| ? |
|
| up vote 2 down vote | You may create local repository on your project For example if you have libs folder in project structure
<repository> <id>ProjectRepo</id><name>ProjectRepo</name><url>file://${project.basedir}/libs</url></repository>
<dependency> <groupId>groupId</groupId><artifactId>artifactId</artifactId><version>version</version></dependency> That is all. For detailed information: How to add external libraries in Maven | ||
| ? |
|
| up vote 1 down vote | Even though it does not exactly fit to your problem, I'll drop this here. My requirements were: Let's talk about (3) first: Just having the jars in a folder and somehow merging them into the final jar will not work for here, since the IDE will not understand this. This means all libraries have to be installed properly. However, I dont want to have everyone installing it using "mvn install-file". In my project I needed metawidget. Here we go: Every time you have a new library, just add a new execution and tell everyone to build the project again (you can improve this process with project hierachies). | ||||||||||
| ? |
|
| up vote 1 down vote | After having really long discussion with CloudBees guys about properly maven packaging of such kind of JARs, they made an interesting good proposal for a solution: Creation of a fake Maven project which attaches a pre-existing JAR as a primary artifact, running into belonged POM install:install-file execution. Here is an example of such kinf of POM: <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-install-plugin</artifactId><version>2.3.1</version><executions><execution><id>image-util-id</id><phase>install</phase><goals><goal>install-file</goal></goals><configuration><file>${basedir}/file-you-want-to-include.jar</file><groupId>${project.groupId}</groupId><artifactId>${project.artifactId}</artifactId><version>${project.version}</version><packaging>jar</packaging></configuration></execution></executions></plugin></plugins> </build>But in order to implement it, existing project structure should be changed. First, you should have in mind that for each such kind of JAR there should be created different fake Maven project (module). And there should be created a parent Maven project including all sub-modules which are : all JAR wrappers and existing main project. The structure could be : root project (this contains the parent POM file includes all sub-modules with module XML element) (POM packaging) JAR 1 wrapper Maven child project (POM packaging) JAR 2 wrapper Maven child project (POM packaging) main existing Maven child project (WAR, JAR, EAR .... packaging) When parent running via mvn:install or mvn:packaging is forced and sub-modules will be executed. That could be concerned as a minus here, since project structure should be changed, but offers a non static solution at the end | ||
| ? |
|
| up vote 0 down vote | This doesn't answer how to add them to your POM, and may be a no brainer, but would just adding the lib dir to your classpath work? I know that is what I do when I need an external jar that I don't want to add to my Maven repos. Hope this helps. | ||
| ? |
|
| up vote 0 down vote | A strange solution I found: using Eclipse
cheers, Balint |
| ? | Was this post useful to you???? |
| up vote 0 down vote | What works in our project is what Archimedes Trajano wrote, but we had in our .m2/settings.xml something like this: <mirror><id>nexus</id><mirrorOf>*</mirrorOf><url>http://url_to_our_repository</url></mirror>and the * should be changed to central. So if his answer doesn't work for you, you should check your settings.xml |
?
總結(jié)
以上是生活随笔為你收集整理的Maven用仓库外的jar进行编译的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: maven常见问题问答
- 下一篇: maven优化-repositories