我正在尝试在我的 Maven 项目中使用外部库。因为我希望项目在任何机器上开箱即用,所以我不想使用 mvn install 解决方案。因此,我在我的 pom.xml 中定义了本地存储库:
<dependency>
<groupId>com.test</groupId>
<artifactId>fooLib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
....
<repository>
<id>in-project</id>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
<name>In Project Repo</name>
<url>file://${project.basedir}/libRepo</url>
</repository>
问题是当我替换 libRepo 中的 jar 时(没有更新版本号,因为它只是另一个快照)没有使用这个更新的 jar(旧版本来自 .m2 目录被代替)甚至对于 mvn -U clean install
如何让 maven 更新这个 jar?
编辑: 根据What exactly is a Maven Snapshot and why do we need it? maven 应尝试查找更新版本的 SNAPSHOT 依赖项,“即使在本地存储库中找到了该库的版本”。我的设置有什么问题?
肮脏的解决方案: 基于 Maven 2 assembly with dependencies: jar under scope "system" not included 的回答以下扩展我的原始解决方案似乎有效:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>hack-binary</id>
<phase>validate</phase>
<configuration>
<file>${repo.path.to.jar}</file>
<repositoryLayout>default</repositoryLayout>
<groupId>com.test</groupId>
<artifactId>fooLib</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
正如对该解决方案的评论中提到的,它不能单独工作,因此它与 in-project 存储库结合使用(当依赖项在本地 .m2 中不可用时,它会工作 存储库),第二部分在每次构建期间刷新 .m2。
然而,我仍然不清楚为什么普通的“SNAPSHOT”机制不起作用(即当前的脏解决方案也可以在没有 SNAPSHOT 的情况下工作,因为本地 .m2 repo 每次都会明确更新)。有没有更清洁的方法?
解决方案(基于 Aaron 的回答和讨论):问题是我尝试使用 install-file 将文件安装到 libRepo 中。实际的解决方案是如果库更新,使用
mvn deploy:deploy-file -Dfile=fooLib.jar -DgroupId=com.test \
-DartifactId=fooLib -Dversion=1.0-SNAPSHOT -Dpackaging=jar \
-Durl=file://..\libRepo -DrepositoryId=in-project
将其部署到 repo。正确部署后,maven 会正确处理快照。
最佳答案
如果为此使用存储库,那么 Maven 会将 JAR 复制一次到它的本地存储库中(通常在 $HOME/.m2/repository/ 中)。除非版本号改变,否则 Maven 不会认为这个文件已经改变,也不会复制它。请注意,版本号是 Maven 唯一查看的内容;它不关心校验和、文件大小或日期。
顺便说一句,快照在内部被分配了一个版本号,目的就是为了:这样 Maven 可以在内部注意到快照已经更新。
我建议使用 system dependency反而。这样,实际的 JAR 将被添加到类路径中(无需任何复制或内容)。您也不需要为此方法复制 repo 结构,它会清楚地传达您的意图。
[编辑] 我知道 Maven 以不同方式处理范围 system 的依赖关系。不知道有没有意义(如果用依赖编译,肯定能用它跑?)
在我看来,您有以下选择:
使用 deploy:deploy-file 将依赖项安装到您的 libRepo 中而不是自己复制。这应该以这样一种方式更新元数据,当您在真实项目上再次运行 mvn install 时,Maven 将再次复制它。
请注意,file:install 不起作用。文件插件用于访问本地存储库,但您需要使用知道如何更新共享/服务器存储库的部署插件。
将依赖项安装到您的本地存储库中;我建议为此使用一个脚本,您可以将其包含在您的项目中。这样,您就可以避免所有问题,并且可以轻松地在新机器上进行设置。
更改依赖项的版本号,但这很乏味,而且当依赖项的实际版本号更改时,您可能会遇到麻烦。
为您的公司设置本地存储库服务器并将依赖项部署到它。这将需要几个小时,但 a) 您将获得所有依赖项的本地缓存,从而使您的初始构建更快,并且 b) 它将使其他开发人员的设置更快。
关于java - Maven 3 不从本地存储库更新快照依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22015685/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht