Не удается найти определение класса, когда я создаю приложение Spring Boot с Maven от Jenkins и выполняю файл JAR? - PullRequest
0 голосов
/ 08 июня 2018
  • Я полагаю, он не может найти путь к классу.Потому что я могу запустить JAR-файл JAR в локальной среде IDE ( IntelliJ IDEA ).Я использую приведенные ниже фрагменты кода для печати информации о пути к классам.

    ClassLoader cl = ClassLoader.getSystemClassLoader(); URL[] urls = ((URLClassLoader)cl).getURLs(); if (urls == null || urls.length == 0) { System.out.println("Is this a empty classpath?"); } for(URL url: urls){ System.out.println("This is classpath:" + url.getFile()); }

Когда я нажимаю кнопку Выполнить в IntelliJ IDEA, онаможет перечислить все классы зависимостей, например, Это верно.

Это classpath: /Users/admin/.m2/repository/org/springframework/boot/spring-boot-starter/1.5.10.RELEASE / spring-boot-starter-1.5.10.RELEASE.jar Это путь к классу: /Users/admin/.m2/repository/org/springframework/boot/spring-boot/1.5.10.RELEASE/spring-boot-1.5.10.RELEASE.jar

Но когда я запускаю его локально, он просто печатает одно сообщение.Это просто мой каталог JAR-пакетов.Это неправильно.

  • Я прочитал документацию о файле манифеста.Он содержит файл JAR.Он находится в каталоге main / resources.Но у него нет префикса каталога.Он сгенерирован IntelliJ IDEA автоматически.И я разархивирую пакет JAR, чтобы проверить файл META-INF / MANIFEST.MF.Он также содержит ключ Main-Class.

    Manifest-Version: 1.0 Class-Path: spring-data-rest-core-2.6.10.RELEASE.jar mapstruct-1.1.0.F inal.jar logback-core-1.1.11.jar javax.transaction-api-1.2.jar

  • Я проверяю свой файл pom.xml.Он имеет конфигурацию maven-jar-plugin.Я закомментирую classpathPrefix и classpathLayoutType.Я считаю, что это бесполезно.

    <plugin> <!-- Build an executable JAR --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <!--<classpathPrefix>lib/</classpathPrefix>--> <mainClass>com.hzlf.LetFunGoApplication</mainClass> <!--<classpathPrefix>/Users/admin/.m2/repository</classpathPrefix>--> <!--<classpathLayoutType>repository</classpathLayoutType>--> </manifest> </archive> </configuration> </plugin>

    Я сомневаюсь, что это неправильная конфигурация для этого maven-jar-plugin.Его classPathPrefix является относительным путем.Как я могу написать это правильно о хранилище?Мой локальный домашний каталог Maven - /Users/admin/.m2/.В моем контейнере Docker это /root/.m2.

  • Я использую файл Jenkinsfile, чтобы извлечь изображение из концентратора Docker в моем проекте.Вот моя конфигурация Jenkinsfile.В файле deliver.sh просто запустите пакет JAR.

    pipeline { agent { docker { image 'maven:3-alpine' args '-v $HOME/.m2:/root/.m2' } } stages { stage('build') { steps { sh 'mvn --version' sh 'mvn clean package' } } stage('Test') { steps { sh 'mvn test' } post { always { junit 'target/surefire-reports/*.xml' } } } stage('Deliver') { steps { sh './jenkins/scripts/deliver.sh' } } } } Это информация об ошибке.Это смущало меня долгое время.

    Ошибка: произошла ошибка JNI, проверьте вашу установку и попробуйте еще раз Исключение в потоке "main" java.lang.NoClassDefFoundError: org / springframework / boot / autoconfigure/ web / HttpMessageConverters в java.lang.Class.getDeclaredMethods0 (собственный метод) в java.lang.Class.privateGetDeclaredMethods (Class.java:2701) в java.lang.Class.privateGetMethodRecursive (Class.javagg) 48.Class.getMethod0 (Class.java:3018) в java.lang.Class.getMethod (Class.java:1784) в sun.launcher.LauncherHelper.validateMainClass (LauncherHelper.java:544) в sun.laainher.LauncherHelpercheLauncherHelper.java:526) Вызывается: java.lang.ClassNotFoundException: org.springframework.boot.autoconfigure.web.HttpMessageConverters в java.net.URLClassLoader.findClass (URLClassLoader.java:38lC.Class.Lava.Llass.Class.Class.Class.Class.Class.ClassLoader.java:424) в sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:335) в java.lang.ClassLoader.loadClass (ClassLoader.java:357) ... 7 подробнее [Трубопроводная]} [Трубопроводная] // этап [трубопровода]} $ Docker остановка --time = 1 693b10dd721c5780761b00eef880b793f6fa2e94afb77e9ffbac9474360f8a5f $ Докер гт -f 693b10dd721c5780761b00eef880b793f6fa2e94afb77e9ffbac9474360f8a5f [Трубопроводная] // withDockerContainer [Трубопроводная]}[Pipeline] // withEnv [Pipeline]} [Pipeline] // узел [Pipeline] Конец конвейера ERROR: скрипт вернул код выхода 1 Завершено: FAILURE

    1 : https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html [2]: https://i.stack.imgur.com/CaMnb.png [3]: https://i.stack.imgur.com/kbVvJ.png

1 Ответ

0 голосов
/ 03 августа 2018

Я разрешаю это, изменив свой файл delivery.shЯ не знаю настоящую причину, но это работает.Я просто удаляю этап тестирования и этап доставки.Я предполагаю, что это вытекает из опции 'post' в delivery.sh.

pipeline {
    agent {
        docker {
            image 'maven:3-alpine'
            args '-v $HOME/.m2:/root/.m2'
        }
    }
    stages {
        stage('build') {
            steps {
                sh 'mvn --version'
                sh 'mvn clean package'
            }
        }
    }
}
...