เป็นวิธีที่ง่ายที่สุดในการดึงหมายเลขรุ่นจากรหัส pom.xml ของ Maven ในรหัสคือโดยทางโปรแกรม?
เป็นวิธีที่ง่ายที่สุดในการดึงหมายเลขรุ่นจากรหัส pom.xml ของ Maven ในรหัสคือโดยทางโปรแกรม?
คำตอบ:
สมมติว่าคุณใช้ Java คุณสามารถ
สร้าง.properties
ไฟล์ใน (โดยทั่วไป) src/main/resources
ไดเรกทอรีของคุณ(แต่ในขั้นตอนที่ 4 คุณสามารถบอกให้มันดูที่อื่น)
กำหนดค่าของคุณสมบัติบางอย่างใน.properties
ไฟล์ของคุณโดยใช้คุณสมบัติ Maven มาตรฐานสำหรับเวอร์ชันโครงการ: foo.bar=${project.version}
ในโค้ด Java ของคุณให้โหลดค่าจากไฟล์คุณสมบัติเป็นทรัพยากรจาก classpath (google สำหรับตัวอย่างมากมายของวิธีการทำเช่นนี้ แต่นี่เป็นตัวอย่างสำหรับ starters )
ใน Maven ให้เปิดใช้งานการกรองทรัพยากรซึ่งจะทำให้ Maven คัดลอกไฟล์นั้นไปยังคลาสเอาต์พุตของคุณและแปลทรัพยากรระหว่างการคัดลอกนั้นแปลความหมายของคุณสมบัติ คุณสามารถหาข้อมูลได้ที่นี่แต่ส่วนใหญ่คุณทำได้ใน pom ของคุณ:
<สร้าง> <ทรัพยากร> <ทรัพยากร> <ไดเรกทอรี> src / main ทรัพยากร / </ ไดเรกทอรี> <กรอง> จริง </ กรอง> </ ทรัพยากร> </ ทรัพยากร> </ สร้าง>
นอกจากนี้คุณยังจะได้รับคุณสมบัติมาตรฐานอื่น ๆ เช่นproject.name
, project.description
หรือแม้กระทั่งคุณสมบัติโดยพลการที่คุณใส่ใน pom ของคุณ<properties>
ฯลฯ ทรัพยากรกรองรวมกับโปรไฟล์ Maven สามารถให้คุณสร้างพฤติกรรมตัวแปรเวลาที่สร้าง เมื่อคุณระบุโปรไฟล์เมื่อรันไทม์ด้วย-PmyProfile
นั่นสามารถเปิดใช้งานคุณสมบัติที่สามารถแสดงในบิลด์ของคุณ
src/main/resources
เนื่องจากอาจประมวลผลไฟล์ทั้งหมดที่อยู่ในไดเรกทอรีนี้รวมถึงไฟล์ไบนารี เพื่อหลีกเลี่ยงพฤติกรรมที่คาดเดาไม่ได้มันจะดีกว่าที่จะทำกรองในsrc/main/resources-filtered
ไดเรกทอรีที่แนะนำที่นี่ อย่างไรก็ตามขอขอบคุณสำหรับเคล็ดลับที่ดีนี้!
คำตอบที่ยอมรับอาจเป็นวิธีที่ดีที่สุดและเสถียรที่สุดในการรับหมายเลขรุ่นลงในแอปพลิเคชันแบบคงที่แต่จริงๆแล้วไม่ได้ตอบคำถามเดิม: วิธีการดึงหมายเลขเวอร์ชันของสิ่งประดิษฐ์จาก pom.xml? ดังนั้นฉันต้องการเสนอทางเลือกอื่นที่แสดงวิธีการทำงานแบบไดนามิกในระหว่างรันไทม์:
คุณสามารถใช้ Maven ได้ เพื่อความแม่นยำมากขึ้นคุณสามารถใช้ห้องสมุด Maven
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.3.9</version>
</dependency>
จากนั้นทำสิ่งนี้ใน Java:
package de.scrum_master.app;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.FileReader;
import java.io.IOException;
public class Application {
public static void main(String[] args) throws IOException, XmlPullParserException {
MavenXpp3Reader reader = new MavenXpp3Reader();
Model model = reader.read(new FileReader("pom.xml"));
System.out.println(model.getId());
System.out.println(model.getGroupId());
System.out.println(model.getArtifactId());
System.out.println(model.getVersion());
}
}
บันทึกคอนโซลมีดังนี้:
de.scrum-master.stackoverflow:my-artifact:jar:1.0-SNAPSHOT
de.scrum-master.stackoverflow
my-artifact
1.0-SNAPSHOT
Update 2017-10-31:เพื่อตอบคำถามติดตามผลของ Simon Sobisch ฉันได้แก้ไขตัวอย่างเช่นนี้:
package de.scrum_master.app;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Application {
public static void main(String[] args) throws IOException, XmlPullParserException {
MavenXpp3Reader reader = new MavenXpp3Reader();
Model model;
if ((new File("pom.xml")).exists())
model = reader.read(new FileReader("pom.xml"));
else
model = reader.read(
new InputStreamReader(
Application.class.getResourceAsStream(
"/META-INF/maven/de.scrum-master.stackoverflow/aspectj-introduce-method/pom.xml"
)
)
);
System.out.println(model.getId());
System.out.println(model.getGroupId());
System.out.println(model.getArtifactId());
System.out.println(model.getVersion());
}
}
package
d jar ปกติ(คลาสการพึ่งพาไม่ได้รวมอยู่) และไม่ทำงานเมื่อบรรจุด้วย maven-assembly-plugin ที่jar-with-dependencies
ฉันได้รับ a java.io.FileNotFoundException: pom.xml
(มันอยู่ในโหลสุดท้ายMETA-INF/maven/my.package/myapp/pom.xml
) - คำใบ้ใด ๆ ที่จะแก้ปัญหานี้?
สิ่งประดิษฐ์ที่บรรจุมีMETA-INF/maven/${groupId}/${artifactId}/pom.properties
ไฟล์ที่มีเนื้อหาเหมือน:
#Generated by Maven
#Sun Feb 21 23:38:24 GMT 2010
version=2.5
groupId=commons-lang
artifactId=commons-lang
แอปพลิเคชั่นหลายตัวใช้ไฟล์นี้เพื่ออ่านเวอร์ชันของแอปพลิเคชั่น / jar ในขณะรันไทม์โดยไม่จำเป็นต้องตั้งค่า
ปัญหาเดียวของวิธีการข้างต้นคือไฟล์นี้ (ปัจจุบัน) สร้างขึ้นในระหว่างpackage
ขั้นตอนและจะไม่ปรากฏในระหว่างการทดสอบ ฯลฯ (มีปัญหาจิราที่จะเปลี่ยนแปลงสิ่งนี้ดูMJAR-76 ) หากนี่เป็นปัญหาสำหรับคุณแล้วแนวทางที่อธิบายโดย Alex เป็นวิธีที่จะไป
นอกจากนี้ยังมีวิธีการที่อธิบายไว้ในวิธีง่ายๆในการแสดงหมายเลขเวอร์ชันแอปของคุณโดยใช้ Maven :
เพิ่มลงใน pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>test.App</mainClass>
<addDefaultImplementationEntries>
true
</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
จากนั้นใช้สิ่งนี้:
App.class.getPackage().getImplementationVersion()
ฉันได้พบวิธีการนี้จะง่ายขึ้น
getImplementationVersion()
null
(เวอร์ชัน maven 3.0.4)
.war
สิ่งประดิษฐ์อย่าลืมใช้maven-war-plugin
แทนmaven-jar-plugin
getImplementationVersion()
คืนค่าว่าง)
หากคุณใช้บรรจุภัณฑ์ mvn เช่น jar หรือ war ให้ใช้:
getClass().getPackage().getImplementationVersion()
มันอ่านคุณสมบัติ "Implementation-Version" ของ META-INF / MANIFEST.MF ที่สร้างขึ้น (ซึ่งถูกตั้งค่าเป็นเวอร์ชันของ pom.xml) ในไฟล์เก็บถาวร
เพื่อเติมเต็มสิ่งที่ @kieste โพสต์ไว้ซึ่งฉันคิดว่าเป็นวิธีที่ดีที่สุดในการให้ Maven บิลด์ข้อมูลมีอยู่ในรหัสของคุณหากคุณใช้ Spring-boot: เอกสารที่http://docs.spring.io/spring-boot/ เอกสาร / ปัจจุบัน / การอ้างอิง / htmlsingle / # การผลิตพร้อมแอปพลิเคชันข้อมูลมีประโยชน์มาก
คุณเพียงแค่ต้องเปิดใช้งานแอคทูเอเตอร์และเพิ่มคุณสมบัติที่คุณต้องการในapplication.properties
หรือapplication.yml
Automatic property expansion using Maven
You can automatically expand info properties from the Maven project using resource filtering. If you use the spring-boot-starter-parent you can then refer to your Maven ‘project properties’ via @..@ placeholders, e.g.
project.artifactId=myproject
project.name=Demo
project.version=X.X.X.X
project.description=Demo project for info endpoint
info.build.artifact=@project.artifactId@
info.build.name=@project.name@
info.build.description=@project.description@
info.build.version=@project.version@
ใช้ห้องสมุดนี้เพื่อความสะดวกในการแก้ปัญหาง่ายๆ เพิ่มในรายการสิ่งที่คุณต้องการแล้วค้นหาด้วยสตริง
System.out.println("JAR was created by " + Manifests.read("Created-By"));
บางครั้งบรรทัดคำสั่ง Maven นั้นเพียงพอเมื่อทำการสคริปต์บางอย่างที่เกี่ยวข้องกับรุ่นของโครงการเช่นสำหรับการดึงสิ่งประดิษฐ์ผ่าน URL จากที่เก็บ:
mvn help:evaluate -Dexpression=project.version -q -DforceStdout
ตัวอย่างการใช้งาน:
VERSION=$( mvn help:evaluate -Dexpression=project.version -q -DforceStdout )
ARTIFACT_ID=$( mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout )
GROUP_ID_URL=$( mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout | sed -e 's#\.#/#g' )
curl -f -S -O http://REPO-URL/mvn-repos/${GROUP_ID_URL}/${ARTIFACT_ID}/${VERSION}/${ARTIFACT_ID}-${VERSION}.jar
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
รับรุ่นโดยใช้ this.getClass().getPackage().getImplementationVersion()
PS อย่าลืมเพิ่ม:
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
จากการอ้างอิงถึงคำตอบของ ketankk :
น่าเสียดายที่การเพิ่มสิ่งนี้สับสนกับวิธีที่แอปพลิเคชันของฉันจัดการกับทรัพยากร:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
แต่การใช้สิ่งนี้ภายในแท็ก <manifest> ของ maven-assemble-plugin ทำให้เคล็ดลับ:
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
ดังนั้นฉันสามารถรับเวอร์ชันโดยใช้
String version = getClass().getPackage().getImplementationVersion();