mirror of
https://github.com/anchore/syft
synced 2024-11-10 14:24:12 +00:00
fix: syft does not handle the case of parsing a jar with multiple poms (#2231)
--------- Signed-off-by: Colm O hEigeartaigh <coheigea@apache.org> Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> Co-authored-by: Christopher Phillips <christopher.phillips@anchore.com>
This commit is contained in:
parent
dc9bc58480
commit
26cdbfc299
9 changed files with 346 additions and 11 deletions
|
@ -263,21 +263,21 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo() (name, versi
|
||||||
pomMatches := j.fileManifest.GlobMatch(false, pomXMLGlob)
|
pomMatches := j.fileManifest.GlobMatch(false, pomXMLGlob)
|
||||||
var pomPropertiesObject pkg.JavaPomProperties
|
var pomPropertiesObject pkg.JavaPomProperties
|
||||||
var pomProjectObject *parsedPomProject
|
var pomProjectObject *parsedPomProject
|
||||||
if len(pomPropertyMatches) == 1 || len(pomMatches) == 1 {
|
|
||||||
// we have exactly 1 pom.properties or pom.xml in the archive; assume it represents the
|
|
||||||
// package we're scanning if the names seem like a plausible match
|
|
||||||
properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, pomPropertyMatches)
|
|
||||||
projects, _ := pomProjectByParentPath(j.archivePath, j.location, pomMatches)
|
|
||||||
|
|
||||||
for parentPath, propertiesObj := range properties {
|
// Find the pom.properties/pom.xml if the names seem like a plausible match
|
||||||
if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name) {
|
properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, pomPropertyMatches)
|
||||||
pomPropertiesObject = propertiesObj
|
projects, _ := pomProjectByParentPath(j.archivePath, j.location, pomMatches)
|
||||||
if proj, exists := projects[parentPath]; exists {
|
|
||||||
pomProjectObject = proj
|
for parentPath, propertiesObj := range properties {
|
||||||
}
|
if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name) {
|
||||||
|
pomPropertiesObject = propertiesObj
|
||||||
|
if proj, exists := projects[parentPath]; exists {
|
||||||
|
pomProjectObject = proj
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name = pomPropertiesObject.ArtifactID
|
name = pomPropertiesObject.ArtifactID
|
||||||
if name == "" && pomProjectObject != nil {
|
if name == "" && pomProjectObject != nil {
|
||||||
name = pomProjectObject.ArtifactID
|
name = pomProjectObject.ArtifactID
|
||||||
|
|
|
@ -1036,6 +1036,7 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
||||||
fixtureName string
|
fixtureName string
|
||||||
expectedPkgs []pkg.Package
|
expectedPkgs []pkg.Package
|
||||||
expectedRelationships []artifact.Relationship
|
expectedRelationships []artifact.Relationship
|
||||||
|
assignParent bool
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
@ -1146,10 +1147,74 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "multiple pom for parent selection regression (pr 2231)",
|
||||||
|
fixtureName: "api-all-2.0.0-sources",
|
||||||
|
assignParent: true,
|
||||||
|
expectedPkgs: []pkg.Package{
|
||||||
|
{
|
||||||
|
Name: "api-all",
|
||||||
|
Version: "2.0.0",
|
||||||
|
Type: pkg.JavaPkg,
|
||||||
|
Language: pkg.Java,
|
||||||
|
PURL: "pkg:maven/org.apache.directory.api/api-all@2.0.0",
|
||||||
|
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar")),
|
||||||
|
Metadata: pkg.JavaArchive{
|
||||||
|
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar",
|
||||||
|
Manifest: &pkg.JavaManifest{
|
||||||
|
Main: map[string]string{
|
||||||
|
"Build-Jdk": "1.8.0_191",
|
||||||
|
"Built-By": "elecharny",
|
||||||
|
"Created-By": "Apache Maven 3.6.0",
|
||||||
|
"Manifest-Version": "1.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
|
Path: "META-INF/maven/org.apache.directory.api/api-all/pom.properties",
|
||||||
|
GroupID: "org.apache.directory.api",
|
||||||
|
ArtifactID: "api-all",
|
||||||
|
Version: "2.0.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "api-asn1-api",
|
||||||
|
Version: "2.0.0",
|
||||||
|
PURL: "pkg:maven/org.apache.directory.api/api-asn1-api@2.0.0",
|
||||||
|
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar")),
|
||||||
|
Type: pkg.JavaPkg,
|
||||||
|
Language: pkg.Java,
|
||||||
|
Metadata: pkg.JavaArchive{
|
||||||
|
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar:org.apache.directory.api:api-asn1-api",
|
||||||
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
|
Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.properties",
|
||||||
|
GroupID: "org.apache.directory.api",
|
||||||
|
ArtifactID: "api-asn1-api",
|
||||||
|
Version: "2.0.0",
|
||||||
|
},
|
||||||
|
PomProject: &pkg.JavaPomProject{
|
||||||
|
Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.xml",
|
||||||
|
ArtifactID: "api-asn1-api",
|
||||||
|
Name: "Apache Directory API ASN.1 API",
|
||||||
|
Description: "ASN.1 API",
|
||||||
|
Parent: &pkg.JavaPomParent{
|
||||||
|
GroupID: "org.apache.directory.api",
|
||||||
|
ArtifactID: "api-asn1-parent",
|
||||||
|
Version: "2.0.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
gap := newGenericArchiveParserAdapter(Config{})
|
gap := newGenericArchiveParserAdapter(Config{})
|
||||||
|
if tt.assignParent {
|
||||||
|
assignParent(&tt.expectedPkgs[0], tt.expectedPkgs[1:]...)
|
||||||
|
}
|
||||||
pkgtest.NewCatalogTester().
|
pkgtest.NewCatalogTester().
|
||||||
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName)).
|
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName)).
|
||||||
Expects(tt.expectedPkgs, tt.expectedRelationships).
|
Expects(tt.expectedPkgs, tt.expectedRelationships).
|
||||||
|
@ -1159,6 +1224,18 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assignParent(parent *pkg.Package, childPackages ...pkg.Package) {
|
||||||
|
for i, jp := range childPackages {
|
||||||
|
if v, ok := jp.Metadata.(pkg.JavaArchive); ok {
|
||||||
|
parent := *parent
|
||||||
|
// PURL are not calculated after the fact for parent
|
||||||
|
parent.PURL = ""
|
||||||
|
v.Parent = &parent
|
||||||
|
childPackages[i].Metadata = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func generateJavaMetadataJarFixture(t *testing.T, fixtureName string) string {
|
func generateJavaMetadataJarFixture(t *testing.T, fixtureName string) string {
|
||||||
fixturePath := filepath.Join("test-fixtures/jar-metadata/cache/", fixtureName+".jar")
|
fixturePath := filepath.Join("test-fixtures/jar-metadata/cache/", fixtureName+".jar")
|
||||||
if _, err := os.Stat(fixturePath); !os.IsNotExist(err) {
|
if _, err := os.Stat(fixturePath); !os.IsNotExist(err) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ CACHE_PATH = $(shell pwd)/cache
|
||||||
|
|
||||||
JACKSON_CORE = jackson-core-2.15.2
|
JACKSON_CORE = jackson-core-2.15.2
|
||||||
SBT_JACKSON_CORE = com.fasterxml.jackson.core.jackson-core-2.15.2
|
SBT_JACKSON_CORE = com.fasterxml.jackson.core.jackson-core-2.15.2
|
||||||
|
API_ALL_SOURCES = api-all-2.0.0-sources
|
||||||
|
|
||||||
$(CACHE_DIR):
|
$(CACHE_DIR):
|
||||||
mkdir -p $(CACHE_DIR)
|
mkdir -p $(CACHE_DIR)
|
||||||
|
@ -12,3 +13,6 @@ $(CACHE_DIR)/$(JACKSON_CORE).jar: $(CACHE_DIR)
|
||||||
|
|
||||||
$(CACHE_DIR)/$(SBT_JACKSON_CORE).jar: $(CACHE_DIR)
|
$(CACHE_DIR)/$(SBT_JACKSON_CORE).jar: $(CACHE_DIR)
|
||||||
cd $(SBT_JACKSON_CORE) && zip -r $(CACHE_PATH)/$(SBT_JACKSON_CORE).jar .
|
cd $(SBT_JACKSON_CORE) && zip -r $(CACHE_PATH)/$(SBT_JACKSON_CORE).jar .
|
||||||
|
|
||||||
|
$(CACHE_DIR)/$(API_ALL_SOURCES).jar: $(CACHE_DIR)
|
||||||
|
cd $(API_ALL_SOURCES) && zip -r $(CACHE_PATH)/$(API_ALL_SOURCES).jar .
|
|
@ -3,3 +3,11 @@
|
||||||
Each directory is the name of a jar to be created (simply a zip) based on the contents of the directory.
|
Each directory is the name of a jar to be created (simply a zip) based on the contents of the directory.
|
||||||
This prevents us from having to create real jars by hand or keep binaries in the repo. This also means we dont need the
|
This prevents us from having to create real jars by hand or keep binaries in the repo. This also means we dont need the
|
||||||
entire jar, only the necessary metadata for testing.
|
entire jar, only the necessary metadata for testing.
|
||||||
|
|
||||||
|
### api-all-2.0.0-sources
|
||||||
|
This fixture is built to simulate the case where we have a jar with multiple pom files discovered when trying to determine the parent.
|
||||||
|
This is a valid case, but not one that we covered before [PR 2231](https://github.com/anchore/syft/pull/2231)
|
||||||
|
|
||||||
|
### jackson-core-2.15.2
|
||||||
|
These two fixtures are built to simulate the case where we would have a duplicate jar
|
||||||
|
regression as seen in [issue #2130](https://github.com/anchore/syft/issues/2130)
|
|
@ -0,0 +1,4 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Built-By: elecharny
|
||||||
|
Created-By: Apache Maven 3.6.0
|
||||||
|
Build-Jdk: 1.8.0_191
|
|
@ -0,0 +1,4 @@
|
||||||
|
#Created by Apache Maven 3.6.0
|
||||||
|
version=2.0.0
|
||||||
|
groupId=org.apache.directory.api
|
||||||
|
artifactId=api-all
|
|
@ -0,0 +1,135 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
<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/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.apache.directory.api</groupId>
|
||||||
|
<artifactId>api-parent</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>api-all</artifactId>
|
||||||
|
<name>Apache Directory API All</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-asn1-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-asn1-ber</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-dsml-engine</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-dsml-parser</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-i18n</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-client-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-codec-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-codec-standalone</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-extras-aci</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-extras-codec</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-extras-codec-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-extras-sp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-extras-trigger</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-extras-util</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-model</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-net-mina</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-schema-converter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-ldap-schema-data</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-util</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<artifactSet>
|
||||||
|
<includes>
|
||||||
|
<include>${project.groupId}</include>
|
||||||
|
</includes>
|
||||||
|
</artifactSet>
|
||||||
|
<promoteTransitiveDependencies>true</promoteTransitiveDependencies>
|
||||||
|
<createSourcesJar>true</createSourcesJar>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,4 @@
|
||||||
|
#Created by Apache Maven 3.6.0
|
||||||
|
version=2.0.0
|
||||||
|
groupId=org.apache.directory.api
|
||||||
|
artifactId=api-asn1-api
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
<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/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.apache.directory.api</groupId>
|
||||||
|
<artifactId>api-asn1-parent</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>api-asn1-api</artifactId>
|
||||||
|
<name>Apache Directory API ASN.1 API</name>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
|
<description>ASN.1 API</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>api-i18n</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestFile>META-INF/MANIFEST.MF</manifestFile>
|
||||||
|
<addMavenDescriptor>false</addMavenDescriptor>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<inherited>true</inherited>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<manifestLocation>META-INF</manifestLocation>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.groupId}.asn1.api</Bundle-SymbolicName>
|
||||||
|
<Export-Package>
|
||||||
|
org.apache.directory.api.asn1;version=${project.version};-noimport:=true,
|
||||||
|
org.apache.directory.api.asn1.util;version=${project.version};-noimport:=true
|
||||||
|
</Export-Package>
|
||||||
|
<Import-Package>
|
||||||
|
org.apache.directory.api.i18n;version=${project.version}
|
||||||
|
</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
Loading…
Reference in a new issue