런타임에 Maven 아티팩트 버전 가져오기
메이븐 아티팩트의 JAR에서 프로젝트를 발견했습니다.version Atribut은 다음 2개의 파일에 포함되어 있습니다.
META-INF/maven/${groupId}/${artifactId}/pom.properties
META-INF/maven/${groupId}/${artifactId}/pom.xml
런타임에 이 버전을 읽을 수 있는 권장 방법이 있습니까?
특정 라이브러리/클래스의 버전 정보를 얻기 위해 Maven 고유 파일에 액세스할 필요가 없습니다.
간단하게 사용할 수 있습니다.getClass().getPackage().getImplementationVersion()
.jar 파일에 저장된 버전 정보를 가져오려면MANIFEST.MF
.
다행히 메이븐은 충분히 똑똑하다. 안타깝게도 Maven은 매니페스트에도 기본적으로 올바른 정보를 쓰지 않습니다!
그 대신, 이 명령어를 수정해야 합니다.<archive>
의 설정 요소maven-jar-plugin
세팅하다addDefaultImplementationEntries
그리고.addDefaultSpecificationEntries
로.true
, 다음과 같이 합니다.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
이 구성을 사내에 도입하는 것이 이상적입니다.pom
아니면 다른 베이스 트레이너일 수도 있어요
의 상세 문서<archive>
요소는 Maven Archive 문서에서 찾을 수 있습니다.
위의 답변에 대한 후속 조치를 취하십시오..war
아티팩트, 동일한 구성을 적용해야만 했습니다.maven-war-plugin
,보다는maven-jar-plugin
:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
이것으로 버전 정보가 에 추가되었습니다.MANIFEST.MF
(프로젝트 기간 중)WEB-INF/lib
의.war
)
다음은 pom.properties에서 버전을 가져와 매니페스트에서 가져오는 방법입니다.
public synchronized String getVersion() {
String version = null;
// try to load from maven properties first
try {
Properties p = new Properties();
InputStream is = getClass().getResourceAsStream("/META-INF/maven/com.my.group/my-artefact/pom.properties");
if (is != null) {
p.load(is);
version = p.getProperty("version", "");
}
} catch (Exception e) {
// ignore
}
// fallback to using Java API
if (version == null) {
Package aPackage = getClass().getPackage();
if (aPackage != null) {
version = aPackage.getImplementationVersion();
if (version == null) {
version = aPackage.getSpecificationVersion();
}
}
}
if (version == null) {
// we could not compute the version so use a blank
version = "";
}
return version;
}
사용하고 있다maven-assembly-plugin
제 메이븐 포장을 위해서요.Joachim Sauer의 답변에서 Apache Maven Archiver를 사용하는 것도 효과적일 수 있습니다.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
<executions>
<execution .../>
</executions>
</plugin>
archiever는 maven 공유 컴포넌트 중 하나이기 때문에 여러 maven Building 플러그인이 사용할 수 있으며 다음과 같은 두 개 이상의 플러그인을 도입할 경우 충돌이 발생할 수 있습니다.archive
설정을 지정합니다.
나는 여기서 두 가지 주요 접근법에 대해 잠시 시간을 보냈지만, 그들은 나에게 효과가 없었다.저는 Netbeans를 빌드에 사용하고 있습니다.더 많은 일이 있을지도 모릅니다.Maven 3에서 몇 가지 오류와 경고가 있었지만 수정은 쉬웠다고 생각합니다.별 거 아니야.
DZone에 관한 이 기사에서 유지보수가 가능하고 구현이 간단해 보이는 답변을 찾았습니다.
이미 리소스/구성 서브폴더가 있고 파일 이름을 app.properties로 지정했습니다.이것에 의해, 서포트 URL등에서 보존할 수 있는 정보를 보다 잘 반영할 수 있습니다.
유일한 경고는 Netbeans가 IDE 필터링을 해제해야 한다는 경고를 보낸다는 것입니다.장소와 방법을 알 수 없습니다.현시점에서는 효과가 없습니다.내가 그 다리를 건너야 한다면, 아마도 그것에 대한 작업이 있을 것이다.행운을 빌어요.
Eclipse 및 Maven 빌드에서 이 작업을 실행하려면addDefaultImplementationEntries
★★★★★★★★★★★★★★★★★」addDefaultSpecificationEntries
는 다른합니다.
public synchronized static final String getVersion() {
// Try to get version number from pom.xml (available in Eclipse)
try {
String className = getClass().getName();
String classfileName = "/" + className.replace('.', '/') + ".class";
URL classfileResource = getClass().getResource(classfileName);
if (classfileResource != null) {
Path absolutePackagePath = Paths.get(classfileResource.toURI())
.getParent();
int packagePathSegments = className.length()
- className.replace(".", "").length();
// Remove package segments from path, plus two more levels
// for "target/classes", which is the standard location for
// classes in Eclipse.
Path path = absolutePackagePath;
for (int i = 0, segmentsToRemove = packagePathSegments + 2;
i < segmentsToRemove; i++) {
path = path.getParent();
}
Path pom = path.resolve("pom.xml");
try (InputStream is = Files.newInputStream(pom)) {
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(is);
doc.getDocumentElement().normalize();
String version = (String) XPathFactory.newInstance()
.newXPath().compile("/project/version")
.evaluate(doc, XPathConstants.STRING);
if (version != null) {
version = version.trim();
if (!version.isEmpty()) {
return version;
}
}
}
}
} catch (Exception e) {
// Ignore
}
// Try to get version number from maven properties in jar's META-INF
try (InputStream is = getClass()
.getResourceAsStream("/META-INF/maven/" + MAVEN_PACKAGE + "/"
+ MAVEN_ARTIFACT + "/pom.properties")) {
if (is != null) {
Properties p = new Properties();
p.load(is);
String version = p.getProperty("version", "").trim();
if (!version.isEmpty()) {
return version;
}
}
} catch (Exception e) {
// Ignore
}
// Fallback to using Java API to get version from MANIFEST.MF
String version = null;
Package pkg = getClass().getPackage();
if (pkg != null) {
version = pkg.getImplementationVersion();
if (version == null) {
version = pkg.getSpecificationVersion();
}
}
version = version == null ? "" : version.trim();
return version.isEmpty() ? "unknown" : version;
}
Java 빌드가 타겟클래스를 "target/classes" 이외의 장소에 배치하는 경우 segmentsToRemove 값을 조정해야 할 수 있습니다.
spring boot 어플리케이션에서는 최근 jdk를 버전 12로 업데이트하기 전까지 승인된 답변의 솔루션이 작동했습니다.다른 모든 답변도 시도해 봤지만 제대로 작동하지 않았다.
첫 했습니다. 뒤에 .@SpringBootApplication
@PropertySources({
@PropertySource("/META-INF/maven/com.my.group/my-artefact/pom.properties")
})
값및.appVersion
이치노
@Value("${version}")
private String appVersion;
그게 도움이 됐으면 좋겠어요.
스프링 부트를 사용하는 경우 BuildProperties 클래스를 사용할 수 있습니다.
오픈에서 다음 토막을 참고하십시오.API 컨피규레이션클래스의 예:
@Configuration
@RequiredArgsConstructor // <- lombok
public class OpenApi {
private final BuildProperties buildProperties; // <- you can also autowire it
@Bean
public OpenAPI yourBeautifulAPI() {
return new OpenAPI().info(new Info()
.title(buildProperties.getName())
.description("The description")
.version(buildProperties.getVersion())
.license(new License().name("Your company")));
}
}
매우 늦은 답변인 것은 알지만, 이 링크에서 제가 한 일을 공유하겠습니다.
pom.xml에 다음 코드를 추가했습니다.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
또한 이 어드바이스 컨트롤러는 버전을 모델 속성으로 가져옵니다.
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.info.BuildProperties;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
@ControllerAdvice
public class CommonControllerAdvice
{
@Autowired
BuildProperties buildProperties;
@ModelAttribute("version")
public String getVersion() throws IOException
{
String version = buildProperties.getVersion();
return version;
}
}
제가 찾은 가장 우아한 해결책은 J사의 것입니다.Chomel: 링크
속성을 가진 해킹은 필요 없습니다.향후 링크가 끊기는 문제를 피하기 위해 여기서 링크를 복제합니다.
YourClass.class.getPackage().getImplementationVersion();
그리고 (아직 manifest 파일이 jar/war에 없는 경우 Intelij Idea의 Maven에 이미 포함되어 있습니다) pom.xml의 작은 변경도 필요합니다.
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
...
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
...
Maven과 호환되며 모든 클래스(따라서 서드파티 클래스에도 사용 가능)에서 사용할 수 있는 심플한 솔루션:
private static Optional<String> getVersionFromManifest(Class<?> clazz) {
try {
File file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI());
if (file.isFile()) {
JarFile jarFile = new JarFile(file);
Manifest manifest = jarFile.getManifest();
Attributes attributes = manifest.getMainAttributes();
final String version = attributes.getValue("Bundle-Version");
return Optional.of(version);
}
} catch (Exception e) {
// ignore
}
return Optional.empty();
}
없는 .Optional<>
thatnull
존재하지 않는 경우(빠른 디버깅/디버깅용):
private static String getVersionFromManifest(Class<?> clazz) {
try {
File file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI());
if (file.isFile()) {
JarFile jarFile = new JarFile(file);
Manifest manifest = jarFile.getManifest();
Attributes attributes = manifest.getMainAttributes();
return attributes.getValue("Bundle-Version");
}
} catch (Exception e) {
// ignore
}
return null;
}
Maven 프로젝트와 함께 전쟁 파일에 있는 EJB용 Java 8 변형.EAP 7.0에서 테스트 완료.
@Log4j // lombok annotation
@Startup
@Singleton
public class ApplicationLogic {
public static final String DEVELOPMENT_APPLICATION_NAME = "application";
public static final String DEVELOPMENT_GROUP_NAME = "com.group";
private static final String POM_PROPERTIES_LOCATION = "/META-INF/maven/" + DEVELOPMENT_GROUP_NAME + "/" + DEVELOPMENT_APPLICATION_NAME + "/pom.properties";
// In case no pom.properties file was generated or wrong location is configured, no pom.properties loading is done; otherwise VERSION will be assigned later
public static String VERSION = "No pom.properties file present in folder " + POM_PROPERTIES_LOCATION;
private static final String VERSION_ERROR = "Version could not be determinated";
{
Optional.ofNullable(getClass().getResourceAsStream(POM_PROPERTIES_LOCATION)).ifPresent(p -> {
Properties properties = new Properties();
try {
properties.load(p);
VERSION = properties.getProperty("version", VERSION_ERROR);
} catch (Exception e) {
VERSION = VERSION_ERROR;
log.fatal("Unexpected error occured during loading process of pom.properties file in META-INF folder!");
}
});
}
}
언급URL : https://stackoverflow.com/questions/2712970/get-maven-artifact-version-at-runtime
'source' 카테고리의 다른 글
32비트 정수가 오버플로우 했을 경우 64비트 길이 구조가 아닌 40비트 구조를 사용할 수 있습니까? (0) | 2022.09.01 |
---|---|
페이지 새로고침 또는 직접 액세스 후 vuex-module에서 인증에 액세스할 수 없음 (0) | 2022.09.01 |
서로 다른 메시지를 두 파일에 기록하기 위한 로그백 (0) | 2022.09.01 |
컴포넌트 슬롯 내에서 계산된 속성을 사용할 수 있습니까? (0) | 2022.09.01 |
Eclipse의 Java 프로젝트:java.lang 타입.개체를 확인할 수 없습니다.필요한 .class 파일에서 간접적으로 참조됩니다. (0) | 2022.09.01 |