sapjco3.jar имеет проблемы с соглашением об именах Maven (Springboot)
Я пытаюсь скомпилировать сервер интеграции, используя среду Java Springboot. Я использую Maven для компиляции файла JAR, но у меня постоянно возникает проблема с тем, как Maven хранит файлы JAR в репозиториях.
Jar, с которым я работаю, это sapjco3.jar, который аварийно завершает работу при запуске (не в пакете), потому что ему необходимо имя sapjco3.jar. Потому что соглашение по именованию репо Maven:
/%groupId%/%artifactId%/%version%/%artifactId%-%version%.jar
Библиотека в конечном итоге называется sapjco3-3.0.jar.
Есть ли какой-то способ вставить мой sapjco3.jar в мое приложение без использования репозитория (я не смог добавить его в java.library.path или отредактировать записи и xml в каталоге ~/.m2). Иначе, есть ли способ сценария переименовать его после того, как он вставлен?
Кстати, моя платформа - Ubuntu 14.04 LTS.
Мой файл POM (отсутствует заголовок xml, потому что Stackru неправильно его анализирует):
<modelVersion>4.0.0</modelVersion>
<name>SampleIntegrationServer</name>
<description>Sample Integration Server</description>
<groupId>com.Sample</groupId>
<artifactId>SampleIntegrationServer</artifactId>
<packaging>jar</packaging>
<version>0.0.2</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<spring-cloud-aws-version>1.0.4.RELEASE</spring-cloud-aws-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-ws</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-velocity</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
<version>${spring-cloud-aws-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-aws-messaging</artifactId>
<version>${spring-cloud-aws-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jt400</groupId>
<artifactId>jt400</artifactId>
<version>6.7</version>
</dependency>
<dependency>
<groupId>com.sap</groupId>
<artifactId>sapjco3</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.3.RELEASE</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<includeEmptyDirs>true</includeEmptyDirs>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</build>
Авария:
Factory method 'createSapConnection' threw exception; nested exception is java.lang.ExceptionInInitializerError: JCo initialization failed with java.lang.ExceptionInInitializerError: Illegal JCo archive "sapjco3-3.0.jar". It is not allowed to rename or repackage the original archive "sapjco3.jar".
Я просто хочу это построить!!
Спасибо
1 ответ
Я решил эту проблему с пользовательским макетом
import org.springframework.boot.loader.tools.Layouts.Jar;
public class ResistantToSapjco3JarLayout extends Jar implements CustomLoaderLayout {
@Override
public void writeLoadedClasses(LoaderClassesWriter writer) throws IOException {
// do Spring Boot defaults
writer.writeLoaderClasses();
URL jcoClassUrl = getClass().getClassLoader().getResource("com/sap/conn/jco/JCo.class");
if (jcoClassUrl == null) {
throw new IllegalStateException("No sapjco3 JAR on plugin classpath. "
+ "Make sure sapjco3 is added to spring-boot-maven-plugin dependency section");
}
if (!jcoClassUrl.toString().startsWith("jar:file")) {
throw new IllegalStateException("sapjco3 is not JAR");
}
JarURLConnection jarUrlConnection = (JarURLConnection) jcoClassUrl.openConnection();
JarFile sapjco3Jar = jarUrlConnection.getJarFile();
JarWriter jarWriter = (JarWriter) writer;
jarWriter.writeNestedLibrary("BOOT-INF/lib/",
new Library("sapjco3.jar", new File(sapjco3Jar.getName()), LibraryScope.COMPILE, false));
}
}
pom.xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layoutFactory implementation="com.company.ResistantToSapjco3JarLayoutFactory" />
<excludeArtifactIds>sapjco3</excludeArtifactIds>
</configuration>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>resistant-to-sapjco3</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>sapjco3</groupId>
<artifactId>sapjco3</artifactId>
<version>3.0.13</version>
</dependency>
</dependencies>
</plugin>
ResistantToSapjco3JarLayoutFactory
public class ResistantToSapjco3JarLayoutFactory implements LayoutFactory {
@Override
public Layout getLayout(File source) {
return new ResistantToSapjco3JarLayout();
}
}
Я решил проблему с помощью плагина тени для maven. Наличие зависимости maven для sapjco3 с предоставленной областью:
<dependency>
<groupId>com.sap.conn.jco</groupId>
<artifactId>sapjco3</artifactId>
<version>${sapjco3.version}</version>
<scope>provided</scope>
</dependency>
Затем работа выполняется путем копирования библиотеки при затенении и исключения ее, когда плагин spring maven добавляет свою версию, так что у нас есть исходная:
<build>
<finalName>price</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<stripVersion>true</stripVersion>
<includeArtifactIds>sapjco3</includeArtifactIds>
<includeTypes>jar</includeTypes>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
<createDependencyReducedPom>true</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
<resource>BOOT-INF/lib/sapjco3.jar</resource>
<file>sapjco3.jar</file>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.7.RELEASE</version>
<configuration>
<excludeGroupIds>com.sap.conn.jco</excludeGroupIds>
</configuration>
</plugin>
...