답변:
특정 라이브러리 / 클래스의 버전 정보를 얻기 위해 Maven 특정 파일에 액세스 할 필요는 없습니다.
getClass().getPackage().getImplementationVersion()
.jar-files에 저장된 버전 정보를 얻는 데 사용할 수 있습니다 MANIFEST.MF
. 운 좋게도 Maven은 충분히 영리합니다 불행하게도 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 설명서를 참조하십시오 .
A에 대한 위의 대답을 따르 .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
프로젝트의에 .jar
(포함 WEB-INF/lib
의 .war
)
null
하면 war 파일의 MANIFEST.MF에 올바른 정보가 포함되어 있지만 결과는 항상 있습니다.
<archiveClasses>true</archiveClasses>
– 그 이후로 안정적으로 작동합니다.
다음은 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;
}
나는 여기에 두 가지 주요 접근 방식에 시간을 보냈지 만 그들은 나를 위해 운동하지 않았습니다. 빌드에 Netbeans를 사용하고 있으며 더 많은 작업이있을 수 있습니다. Maven 3의 일부 오류와 경고가 있지만 일부는 쉽게 수정할 수 있다고 생각합니다. 더 큰.
DZone 의이 기사에서 유지 관리 가능하고 구현하기 쉬운 답변을 찾았습니다.
이미 resources / config 하위 폴더를 가지고 있고 지원 URL과 같이 유지할 수있는 것들을 더 잘 반영하기 위해 app.properties라는 파일 이름을 지정했습니다.
유일한주의 사항은 Netbeans가 IDE에서 필터링을 해제해야한다는 경고를 표시한다는 것입니다. 어디서 / 어떻게 확실하지 않습니다. 이 시점에서는 효과가 없습니다. 다리를 건너야 할 경우 해결 방법이있을 수 있습니다. 행운을 빕니다.
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 plugin에서 사용할 수 있으며, archive
내부 구성을 포함하여 둘 이상의 플러그인이 도입되면 충돌이 발생할 수 있습니다 .
Maven 빌드뿐만 아니라 Eclipse에서도 실행하려면 다른 응답에 설명 된대로 addDefaultImplementationEntries
및 addDefaultSpecificationEntries
pom 항목을 추가 한 후 다음 코드를 사용해야합니다.
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 빌드가 대상 클래스를 "대상 / 클래스"이외의 다른 곳에두면 segmentToRemove의 값을 조정해야합니다.
System.getProperty("user.dir")/pom.xml
. WTP가 아닌 것을 제외하고는 다른 것들에 대해서도 확실히 확신합니다.
.getResource()
또는 을 사용해야 .getResourceAsStream()
합니다.
내 봄 부팅 응용 프로그램에서 허용되는 답변의 솔루션은 최근 jdk를 버전 12로 업데이트 할 때까지 작동했습니다. 다른 모든 답변도 시도했지만 작동하지 못했습니다.
그 시점에서 나는 주석 바로 다음에 스프링 부트 응용 프로그램의 첫 번째 클래스에 아래 줄을 추가했습니다. @SpringBootApplication
@PropertySources({
@PropertySource("/META-INF/maven/com.my.group/my-artefact/pom.properties")
})
나중에 아래 값을 사용하여 값을 사용하려는 클래스의 속성 파일에서 값을 appVersion
가져 와서 프로젝트 버전을 가져옵니다.
@Value("${version}")
private String appVersion;
누군가에게 도움이되기를 바랍니다.
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();
}
maven 프로젝트의 war 파일에서 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!");
}
});
}
}