War Story: Как мы внедряли поддержку Java 11 в Jenkins (RUS)

War Story: Как мы внедряли поддержку Java 11 в Jenkins (RUS)

Сказ о том, как мы внедряли поддержку Java 11 в Jenkins — одном из наиболее популярных серверов автоматизации для CI/CD. Цель доклада — рассказать о том, с какими проблемами мы столкнулись в реальном крупном Maven-проекте, и о том, как мы их решали. Доклад не имеет отношения к Jenkins как таковому, целевая аудитория — разработчики, которые планируют переезд на Java 11.

Как нам удалось поддержать Java 11 и сохранить совместимость с Java 8? Как мы обеспечили сборку и тестирование проектов в Java 9..11? Насколько на нас повлияли новая система модулей, multi-release JARs и несовместимые изменения в Java (reflection, classloading, удаление компонентов Java EE/Jakarta)? И как автоматизировать тестирование, чтобы не переделывать всё с каждым новым релизом Java? И что мы, в конце концов, получили от миграции на Java 11?

Справка: Jenkins имеет огромную кодовую базу: Java, Groovy, нативные библиотеки и даже немного Kotlin. Проект включает сотни зависимостей, 1500+ плагинов, а также десятки стандартных и самописных dev-тулов (Maven, Gradle). Впридачу — 10 лет обратной совместимости и огромное количество легаси-кода. Если вы заметили сходство со своими Java-проектами и думаете о миграции на Java 11, то приходите на доклад :)

568e3391c8b528f2b255443e4cca27ca?s=128

Oleg Nenashev

October 26, 2019
Tweet

Transcript

  1. © 2019 CloudBees, Inc. All Rights Reserved. © 2019 CloudBees,

    Inc. All Rights Reserved. Jenkins.war story Как мы внедряли поддержку Java 11 Олег Ненашев, CloudBees @oleg_nenashev
  2. © 2019 CloudBees, Inc. All Rights Reserved. О чём доклад?

    V - Миграция крупных проектов на Java 11 V - Наш опыт, проблемы и решения V - Java, Maven, стандартные тулы X - Jenkins X - Jenkins X X - Дебри Java 11 2
  3. © 2019 CloudBees, Inc. All Rights Reserved. > whoami @oleg_nenashev

    oleg-nenashev • Principal SW Engineer, CloudBees • Jenkins Core maintainer • Platform SIG leader 3
  4. © 2019 CloudBees, Inc. All Rights Reserved. > whoami -cloudbees

    4 • CloudBees Jenkins Distribution • CloudBees Jenkins Support • Сообщество: Java 11, Jenkinsfile Runner, JCasC https://www.cloudbees.com
  5. © 2019 CloudBees, Inc. All Rights Reserved. Who is Mr.

    Jenkins? 1. Сервер автоматизации 2. CI/CD/DevOps/… 3. 200k+ инсталляций 4. Open-source 5. Большое сообщество 6. >1700 плагинов https://jenkins.io 5
  6. © 2019 CloudBees, Inc. All Rights Reserved. Under the hood

    JENKINS Image: https://www.youtube.com/watch?v=Qae_3RDa6sM 6
  7. © 2019 CloudBees, Inc. All Rights Reserved. 7

  8. © 2019 CloudBees, Inc. All Rights Reserved. 8 Более 50

    тикетов на совместимость с Java 9/10
  9. © 2019 CloudBees, Inc. All Rights Reserved. Java 8 навсегда?

    9
  10. © 2019 CloudBees, Inc. All Rights Reserved. Java 8 навсегда?

    10
  11. © 2019 CloudBees, Inc. All Rights Reserved. 8 11

  12. © 2019 CloudBees, Inc. All Rights Reserved. 12

  13. © 2019 CloudBees, Inc. All Rights Reserved. 13

  14. © 2019 CloudBees, Inc. All Rights Reserved. Июнь 2018 -

    Online Hackathon • 1й день - Pipeline 14
  15. © 2019 CloudBees, Inc. All Rights Reserved. Июнь 2018 -

    Online Hackathon • 2й день - BlueOcean 15
  16. © 2019 CloudBees, Inc. All Rights Reserved. Июнь 2018 -

    Online Hackathon • 5й день - “самое скучное демо на свете” 16
  17. © 2019 CloudBees, Inc. All Rights Reserved. Сентябрь 2018 •

    1 день - поддержка Java 11 17
  18. © 2019 CloudBees, Inc. All Rights Reserved. Java 10 PoC

    - июнь 2018 Java 11 PoC - сентябрь 2018 Java 11 RC - декабрь 2018 Java 11 GA - март 2019 18 ? ? ?
  19. © 2019 CloudBees, Inc. All Rights Reserved. Запустить проект на

    Java 11 - легко, а переехать на Java 11 - сложно 19
  20. © 2019 CloudBees, Inc. All Rights Reserved. Экосистема Jenkins Ядро

    и модули Плагины Дистрибутивы Подпроекты Библиотеки Средства разработки 20
  21. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты Наш Pipeline 21
  22. © 2019 CloudBees, Inc. All Rights Reserved. Наши тулы •

    Maven и немного Gradle • Parent POM и BOM • Maven SureFire + JUnit 4 • SpotBugs, Animal Sniffer, Maven Enforcer • JaCoCo и Cobertura • Свои Maven-плагины 22
  23. © 2019 CloudBees, Inc. All Rights Reserved. Сборка > mvn

    clean package -Djava.level = 11 23 Попытка 1: Maven Compiler Plugin: Unsupported target: 1.11 Попытка 2: Maven Compiler Plugin: Unsupported target: 11
  24. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты Maven-плагины 24
  25. © 2019 CloudBees, Inc. All Rights Reserved. Maven-плагины 25 >

    mvn versions:display-plugin-updates ...
  26. © 2019 CloudBees, Inc. All Rights Reserved. Maven-плагины Maven Compiler

    Plugin Maven Enforcer & Rule Plugin Maven Site GMaven/GMavenPlus Javadoc ... > mvn versions:display-plugin-updates 26
  27. © 2019 CloudBees, Inc. All Rights Reserved. 27 java.lang.IllegalArgumentException at

    org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:185) at org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:168) at org.jenkinsci.bytecode.helper.ClassLoadingReferenceTypeHierachyReader.reader(…) …. at org.jenkinsci.bytecode.helper.ClassLoadingReferenceTypeHierachyReader.getCommonSuperClass(...) at org.jenkinsci.bytecode.NonClassLoadingClassWriter.getCommonSuperClass(NonClassLoadingClassWriter.java:72) at org.kohsuke.asm6.ClassWriter.getMergedType(ClassWriter.java:1736) at org.kohsuke.asm6.Frame.merge(Frame.java:1530) at org.kohsuke.asm6.Frame.merge(Frame.java:1478) at org.kohsuke.asm6.MethodWriter.visitMaxs(MethodWriter.java:1520) at org.kohsuke.asm6.tree.MethodNode.accept(MethodNode.java:835) at org.kohsuke.asm6.commons.JSRInlinerAdapter.visitEnd(JSRInlinerAdapter.java:187) at org.jenkinsci.bytecode.Transformer$1$1.visitEnd(Transformer.java:109) at org.kohsuke.asm6.MethodVisitor.visitEnd(MethodVisitor.java:878) at org.kohsuke.asm6.ClassReader.readMethod(ClassReader.java:1169) at org.kohsuke.asm6.ClassReader.accept(ClassReader.java:727) at org.kohsuke.asm6.ClassReader.accept(ClassReader.java:525) at org.jenkinsci.bytecode.Transformer.transform(Transformer.java:115) at hudson.ClassicPluginStrategy$AntClassLoader2.defineClassFromData(ClassicPluginStrategy.java:857) at jenkins.util.AntClassLoader.getClassFromStream(AntClassLoader.java:1311) at jenkins.util.AntClassLoader.findClassInComponents(AntClassLoader.java:1364) at jenkins.util.AntClassLoader.findClass(AntClassLoader.java:1327) at jenkins.util.AntClassLoader.loadClass(AntClassLoader.java:1080) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499) at org.jenkinsci.plugins.workflow.cps.CpsScript.<init>(CpsScript.java:69) at WorkflowScript.<init>(WorkflowScript
  28. © 2019 CloudBees, Inc. All Rights Reserved. 28 java.lang.IllegalArgumentException at

    org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:185) at org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:168) at org.jenkinsci.bytecode.helper.ClassLoadingReferenceTypeHierachyReader.reader(…) …. at org.jenkinsci.bytecode.helper.ClassLoadingReferenceTypeHierachyReader.getCommonSuperClass(...) at org.jenkinsci.bytecode.NonClassLoadingClassWriter.getCommonSuperClass(NonClassLoadingClassWriter.java:72) at org.kohsuke.asm6.ClassWriter.getMergedType(ClassWriter.java:1736) at org.kohsuke.asm6.Frame.merge(Frame.java:1530) at org.kohsuke.asm6.Frame.merge(Frame.java:1478) at org.kohsuke.asm6.MethodWriter.visitMaxs(MethodWriter.java:1520) at org.kohsuke.asm6.tree.MethodNode.accept(MethodNode.java:835) at org.kohsuke.asm6.commons.JSRInlinerAdapter.visitEnd(JSRInlinerAdapter.java:187) at org.jenkinsci.bytecode.Transformer$1$1.visitEnd(Transformer.java:109) at org.kohsuke.asm6.MethodVisitor.visitEnd(MethodVisitor.java:878) at org.kohsuke.asm6.ClassReader.readMethod(ClassReader.java:1169) at org.kohsuke.asm6.ClassReader.accept(ClassReader.java:727) at org.kohsuke.asm6.ClassReader.accept(ClassReader.java:525) at org.jenkinsci.bytecode.Transformer.transform(Transformer.java:115) at hudson.ClassicPluginStrategy$AntClassLoader2.defineClassFromData(ClassicPluginStrategy.java:857) at jenkins.util.AntClassLoader.getClassFromStream(AntClassLoader.java:1311) at jenkins.util.AntClassLoader.findClassInComponents(AntClassLoader.java:1364) at jenkins.util.AntClassLoader.findClass(AntClassLoader.java:1327) at jenkins.util.AntClassLoader.loadClass(AntClassLoader.java:1080) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499) at org.jenkinsci.plugins.workflow.cps.CpsScript.<init>(CpsScript.java:69) at WorkflowScript.<init>(WorkflowScript at jenkins.util.AntClassLoader.loadClass(AntClassLoader.java:1080) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499) at org.jenkinsci.plugins.workflow.cps.CpsScript.<init>(CpsScript.java:69) at WorkflowScript.<init>(WorkflowScript
  29. © 2019 CloudBees, Inc. All Rights Reserved. 29 java.lang.IllegalArgumentException at

    org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:185) at org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:168) at org.jenkinsci.bytecode.helper.ClassLoadingReferenceTypeHierachyReader.reader(…) …. at org.jenkinsci.bytecode.helper.ClassLoadingReferenceTypeHierachyReader.getCommonSuperClass(...) at org.jenkinsci.bytecode.NonClassLoadingClassWriter.getCommonSuperClass(NonClassLoadingClassWriter.java:72) at org.kohsuke.asm6.ClassWriter.getMergedType(ClassWriter.java:1736) at org.kohsuke.asm6.Frame.merge(Frame.java:1530) at org.kohsuke.asm6.Frame.merge(Frame.java:1478) at org.kohsuke.asm6.MethodWriter.visitMaxs(MethodWriter.java:1520) at org.kohsuke.asm6.tree.MethodNode.accept(MethodNode.java:835) at org.kohsuke.asm6.commons.JSRInlinerAdapter.visitEnd(JSRInlinerAdapter.java:187) at org.jenkinsci.bytecode.Transformer$1$1.visitEnd(Transformer.java:109) at org.kohsuke.asm6.MethodVisitor.visitEnd(MethodVisitor.java:878) at org.kohsuke.asm6.ClassReader.readMethod(ClassReader.java:1169) at org.kohsuke.asm6.ClassReader.accept(ClassReader.java:727) at org.kohsuke.asm6.ClassReader.accept(ClassReader.java:525) at org.jenkinsci.bytecode.Transformer.transform(Transformer.java:115) at hudson.ClassicPluginStrategy$AntClassLoader2.defineClassFromData(ClassicPluginStrategy.java:857) at jenkins.util.AntClassLoader.getClassFromStream(AntClassLoader.java:1311) at jenkins.util.AntClassLoader.findClassInComponents(AntClassLoader.java:1364) at jenkins.util.AntClassLoader.findClass(AntClassLoader.java:1327) at jenkins.util.AntClassLoader.loadClass(AntClassLoader.java:1080) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499) at org.jenkinsci.plugins.workflow.cps.CpsScript.<init>(CpsScript.java:69) at WorkflowScript.<init>(WorkflowScript java.lang.IllegalArgumentException at org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:185) at org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:168) at org.jenkinsci.bytecode.helper.???Reader.reader(…)
  30. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты Maven-плагины Зависимости 30
  31. © 2019 CloudBees, Inc. All Rights Reserved. Lib 1 Lib

    2 Lib 3 Plugin 1 Plugin 2 Plugin 3 Lib 4 Lib 5 Plugin 4 иногда 31
  32. © 2019 CloudBees, Inc. All Rights Reserved. 32 IT IS

    OVER 9000 DEPENDENCIES
  33. © 2019 CloudBees, Inc. All Rights Reserved. Dependency Hell 33

  34. © 2019 CloudBees, Inc. All Rights Reserved. 34 > mvn

    versions:display-updates ... ? ? ?
  35. © 2019 CloudBees, Inc. All Rights Reserved. Нет фиксов для

    Java 9+ Несовместимые изменения Библиотеки требуют Java 9+ Мёртвые проекты 35
  36. © 2019 CloudBees, Inc. All Rights Reserved. ASM 36 https://asm.ow2.io/

  37. © 2019 CloudBees, Inc. All Rights Reserved. java.lang.IllegalArgumentException at org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:185)

    at org.kohsuke.asm6.ClassReader.<init>(ClassReader.java:168) at org.jenkinsci.bytecode.helper.ClassLoadingReferenceTypeHierachyReader.reader(ClassLoadingReferenceTypeHierachyReader.java:64) …. at org.jenkinsci.bytecode.helper.ClassLoadingReferenceTypeHierachyReader.getCommonSuperClass(...) at org.jenkinsci.bytecode.NonClassLoadingClassWriter.getCommonSuperClass(NonClassLoadingClassWriter.java:72) at org.kohsuke.asm6.ClassWriter.getMergedType(ClassWriter.java:1736) at org.kohsuke.asm6.Frame.merge(Frame.java:1530) at org.kohsuke.asm6.Frame.merge(Frame.java:1478) at org.kohsuke.asm6.MethodWriter.visitMaxs(MethodWriter.java:1520) at org.kohsuke.asm6.tree.MethodNode.accept(MethodNode.java:835) at org.kohsuke.asm6.commons.JSRInlinerAdapter.visitEnd(JSRInlinerAdapter.java:187) at org.jenkinsci.bytecode.Transformer$1$1.visitEnd(Transformer.java:109) at org.kohsuke.asm6.MethodVisitor.visitEnd(MethodVisitor.java:878) at org.kohsuke.asm6.ClassReader.readMethod(ClassReader.java:1169) at org.kohsuke.asm6.ClassReader.accept(ClassReader.java:727) at org.kohsuke.asm6.ClassReader.accept(ClassReader.java:525) at org.jenkinsci.bytecode.Transformer.transform(Transformer.java:115) at hudson.ClassicPluginStrategy$AntClassLoader2.defineClassFromData(ClassicPluginStrategy.java:857) at jenkins.util.AntClassLoader.getClassFromStream(AntClassLoader.java:1311) at jenkins.util.AntClassLoader.findClassInComponents(AntClassLoader.java:1364) at jenkins.util.AntClassLoader.findClass(AntClassLoader.java:1327) at jenkins.util.AntClassLoader.loadClass(AntClassLoader.java:1080) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499) at org.jenkinsci.plugins.workflow.cps.CpsScript.<init>(CpsScript.java:69) at WorkflowScript.<init>(WorkflowScript 37 at org.jenkinsci.bytecode.Transformer.transform (Transformer.java:115)
  38. © 2019 CloudBees, Inc. All Rights Reserved. Наш список ASM

    Byte Buddy Reflections Jetty Groovy JNR, JNA Annotation Indexer SezPoz ... 38
  39. © 2019 CloudBees, Inc. All Rights Reserved. • Maven Enforcer

    Plugin https://maven.apache.org/enforcer/maven-enforcer-plugin/ • Extra Enforcer Rules Plugin https://www.mojohaus.org/extra-enforcer-rules/ Что поможет? 39
  40. © 2019 CloudBees, Inc. All Rights Reserved. <plugin> <artifactId>maven-enforcer-plugin</artifactId> <executions>

    <execution> … <configuration> <rules> <enforceBytecodeVersion> <maxJdkVersion>1.8</maxJdkVersion> <ignoredScopes> <ignoredScope>test</ignoredScope> </ignoredScopes> </enforceBytecodeVersion> … </executions> <dependencies> … <artifactId>extra-enforcer-rules</artifactId> … 40
  41. © 2019 CloudBees, Inc. All Rights Reserved. 41 <plugin> <artifactId>maven-enforcer-plugin</artifactId>

    <executions> <execution> … <configuration> <rules> <enforceBytecodeVersion> <maxJdkVersion>1.8</maxJdkVersion> <ignoredScopes> <ignoredScope>test</ignoredScope> </ignoredScopes> </enforceBytecodeVersion> … </executions> <dependencies> … <artifactId>extra-enforcer-rules</artifactId> … <enforceBytecodeVersion> <maxJdkVersion>1.8</maxJdkVersion> <ignoredScopes> <ignoredScope>test</ignoredScope> </ignoredScopes> </enforceBytecodeVersion>
  42. © 2019 CloudBees, Inc. All Rights Reserved. Транзитивные зависимости? ПОТОМУ

    ЧТО MAVEN 42
  43. © 2019 CloudBees, Inc. All Rights Reserved. Транзитивные зависимости •

    И снова Maven Enforcer Plugin • requireUpperBoundDeps <requireUpperBoundDeps> <excludes> <exclude>commons-logging:commons-logging</exclude> <exclude>com.google.code.findbugs:jsr305</exclude> <exclude>net.java.dev.jna:jna</exclude> </excludes> </requireUpperBoundDeps> 43
  44. © 2019 CloudBees, Inc. All Rights Reserved. А Вы обновляете

    зависимости? 44
  45. © 2019 CloudBees, Inc. All Rights Reserved. Технический долг 45

  46. © 2019 CloudBees, Inc. All Rights Reserved. Dependabot dependabot.com, куплен

    GitHub 46
  47. © 2019 CloudBees, Inc. All Rights Reserved. Dependabot • CLI

    и GitHub App • Регулярное сканирование • Поддержка Maven, Gradle и др. 47
  48. © 2019 CloudBees, Inc. All Rights Reserved. Dependabot 48 @oleg_nenashev

    https://speakerdeck.com/onenashev/
  49. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты Maven-плагины Зависимости Наш код 49
  50. © 2019 CloudBees, Inc. All Rights Reserved. 50

  51. © 2019 CloudBees, Inc. All Rights Reserved. JEP 261: Module

    System 51
  52. © 2019 CloudBees, Inc. All Rights Reserved. Никто не заставляет

    использовать модули! 52
  53. 53 ONE DOES NOT SIMPLY IGNORE MODULES IN JAVA11

  54. © 2019 CloudBees, Inc. All Rights Reserved. java.lang.NoClassDefFoundError: java.sql.Date at

    o.a.c.beanutils.ConvertUtilsBean.class$(ConvertUtilsBean.java:157) at o.a.c.beanutils.ConvertUtilsBean.registerOther(ConvertUtilsBean.java:708) at o.a.c.beanutils.ConvertUtilsBean.deregister(ConvertUtilsBean.java:580) at o.a.c.beanutils.ConvertUtilsBean.<init>(ConvertUtilsBean.java:164) at org.kohsuke.stapler.Stapler.<clinit>(Stapler.java:1065) at hudson.model.Node$Mode.<clinit>(Node.java:597) at JENKINS-54426 54
  55. © 2019 CloudBees, Inc. All Rights Reserved. http://java9.wtf/class-loading/ 55

  56. © 2019 CloudBees, Inc. All Rights Reserved. JEP-261 - Restricted

    Bootstrap Class Loader java.sql.* javax.activation.* javax.annotation.* javax.jws.* javax.lang.model.* javax.rmi.* javax.script.* javax.smartcardio.* javax.sql.* javax.tools.* javax.transaction.xa.* javax.xml.bind.* javax.xml.crypto.* javax.xml.soap.* javax.xml.ws.* 56
  57. © 2019 CloudBees, Inc. All Rights Reserved. • Проблема: new

    URLClassloader(null, ...) • Классы из модулей больше недоступны • getPlatformClassLoader() для Java 9+ • А для Java 8 метода нет…. JEP-261 - Restricted Bootstrap Class Loader 57
  58. © 2019 CloudBees, Inc. All Rights Reserved. Platform Classloader. Решение

    private ClassLoader getPlatformClassloader() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { if (isPostJava8()) { return (ClassLoader) ClassLoader.class.getMethod ("getPlatformClassLoader").invoke(null); } return null; // Java 8 } private static boolean isPostJava8() { String javaVersion = System.getProperty("java.version"); return !javaVersion.startsWith("1."); } 58
  59. © 2019 CloudBees, Inc. All Rights Reserved. Кстати о Reflection...

    WARNING: Illegal reflective access by hudson.remoting.RemoteClassLoader (file:/var/jenkins_home/war/WEB-INF/lib/remoting-3.7.jar) to method java.lang.ClassLoader.getClassLoadingLock(java.lang.String) at h.r.RemoteClassLoader.<clinit>(RemoteClassLoader.java:330) at h.r.MultiClassLoaderSerializer$Output.annotateClass(MultiClassLoaderSerializer.java:69) at java.base/java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1291) at java.base/java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1232) 59 JENKINS-46724
  60. © 2019 CloudBees, Inc. All Rights Reserved. Кстати о Reflection...

    WARNING: Illegal reflective access by hudson.remoting.RemoteClassLoader (file:/var/jenkins_home/war/WEB-INF/lib/remoting-3.7.jar) to method java.lang.ClassLoader.getClassLoadingLock(java.lang.String) at h.r.RemoteClassLoader.<clinit>(RemoteClassLoader.java:330) at h.r.MultiClassLoaderSerializer$Output.annotateClass(MultiClassLoaderSerializer.java:69) at java.base/java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1291) at java.base/java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1232) JENKINS-46724 60 TL;DR: setAccessible(true) - это плохо Crash в Java 9 EA по-умолчанию Предупреждение в логах для Java 9+
  61. © 2019 CloudBees, Inc. All Rights Reserved. Illegal Reflective Access

    • Internal Libraries • Upstream Dependencies • Object serialization frameworks Escape hatch: “--illegal-access=permit” 61
  62. © 2019 CloudBees, Inc. All Rights Reserved. Удалённые компоненты sun.misc.Unsafe

    Java Web Start JAXB CORBA API: методы и классы ... 62
  63. © 2019 CloudBees, Inc. All Rights Reserved. • Удалена из

    JDK • Доступна через Jakarta, но почти не поддерживается • В итоге – свой плагин Наша боль – java.xml.bind (JAXB) 63 java -p jaxb-api.jar:javax.activation.jar --add-modules java.xml.bind,java.activation ... -cp jaxb-core.jar:jaxb-impl.jar -jar jenkins.war …
  64. © 2019 CloudBees, Inc. All Rights Reserved. Удалённые API 64

  65. © 2019 CloudBees, Inc. All Rights Reserved. java.lang.UNIXProcess#destroyProcess() 65

  66. © 2019 CloudBees, Inc. All Rights Reserved. Подходы к совместимому

    коду 66 Reflection Class#getDeclaredMethod() Class#getDeclaredField() setAccessible() …
  67. © 2019 CloudBees, Inc. All Rights Reserved. Подходы к совместимому

    коду 67 Reflection Multi-Release JAR (JEP-238) JAR content root A.class B.class C.class META-INF MANIFEST.MF versions 9 A.class B.class 10 A.class Class#getDeclaredMethod() Class#getDeclaredField() setAccessible() …
  68. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты Maven-плагины Зависимости Наш код 68
  69. © 2019 CloudBees, Inc. All Rights Reserved. Собирать на Java

    8, тестировать с Java 11? 69
  70. © 2019 CloudBees, Inc. All Rights Reserved. Maven Surefire -

    Тестирование с Java 11 … <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <jvm>/path/to/jdk11/bin/java</jvm> </configuration> </plugin> … 70
  71. © 2019 CloudBees, Inc. All Rights Reserved. Maven Surefire -

    Подключение модулей … <configuration> <jvm>/path/to/jdk11/bin/java</jvm> <argLine>-p jaxb-api.jar:javax.activation.jar --add-modules java.xml.bind,java.activation ... -cp jaxb-core.jar:jaxb-impl.jar</argLine> ... </configuration> … 71
  72. © 2019 CloudBees, Inc. All Rights Reserved. Что не так?

    Тестовые зависимости Несовместимые Maven- плагины Несовместимые тесты 72
  73. © 2019 CloudBees, Inc. All Rights Reserved. Mockito ASM, ASM,

    ASM Минимальные версии mockito-core 2.23.4+ Mockito почти совместим JENKINS-55098 73
  74. © 2019 CloudBees, Inc. All Rights Reserved. PowerMock Минимальные версии

    powermock-module-junit4:2.0.0-RC4 powermock-api-mockito2:2.0.0-RC4 objenesis:3.0.1 PowerMock несовместим JENKINS-55098 74
  75. © 2019 CloudBees, Inc. All Rights Reserved. PowerMock 75

  76. © 2019 CloudBees, Inc. All Rights Reserved. Тесты только на

    Java 8? 76
  77. © 2019 CloudBees, Inc. All Rights Reserved. CORBA* 77 *

    мы её не используем
  78. © 2019 CloudBees, Inc. All Rights Reserved. CORBA – Риск

    RCE при десериализации* Мастер Агент RPC Системные вызовы RemoteInputStream/ RemoteOutputStream Classloading Сериализация обьектов с readResolve() * Анонс Foxglove Security, 2015
  79. © 2019 CloudBees, Inc. All Rights Reserved. • Мы не

    используем CORBA • Но у нас есть тесты на deserialization • Multi-Release Test JAR не работают ☹ CORBA. Удалена в JDK11 (JEP-320) 79
  80. © 2019 CloudBees, Inc. All Rights Reserved. Тесты только на

    Java 8? 80
  81. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты 81
  82. © 2019 CloudBees, Inc. All Rights Reserved. • Animal Sniffer

    • FindBugs => SpotBugs • JaCoCo, Cobertura • Access Modifier (@Restricted) • ... Что нам пришлось обновлять? 82
  83. © 2019 CloudBees, Inc. All Rights Reserved. SpotBugs 3.1.8+ (№711)

    83 FindBugs
  84. © 2019 CloudBees, Inc. All Rights Reserved. 84 client.setServerKeyVerifier(verifier); client.start();

    try (ClientSession session = cf.getSession()) { /// .... } finally { client.stop(); }
  85. © 2019 CloudBees, Inc. All Rights Reserved. 85 client.setServerKeyVerifier(verifier); client.start();

    try (ClientSession session = cf.getSession()) { /// .... } finally { // RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE client.stop(); }
  86. © 2019 CloudBees, Inc. All Rights Reserved. SpotBugs 3.1.8+ -

    не панацея 86
  87. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты 87
  88. © 2019 CloudBees, Inc. All Rights Reserved. Jenkins-on-Jenkins 88 1.

    Зеркала с JDK (ZIP Installer) 2. Тестовые тулы 3. Docker-образы агентов 4. Docker-образы для всех тулов 5. Библиотеки Pipeline 6. Сами Pipeline https://ci.jenkins.io/
  89. © 2019 CloudBees, Inc. All Rights Reserved. Мы слишком привыкли

    к Java 8 89
  90. © 2019 CloudBees, Inc. All Rights Reserved. • Java 8

    и 11 • Linux и Windows • Разные версии ядра Jenkins • Версии/дистрибутивы Java Конфигурации 90
  91. © 2019 CloudBees, Inc. All Rights Reserved. Jenkins-on-Jenkins. Сборка ядра

    https://ci.jenkins.io/blue/organizatio ns/jenkins/Core%2Fjenkins/detail/j ava11-support/18/pipeline 91
  92. © 2019 CloudBees, Inc. All Rights Reserved. • Jenkins Acceptance

    Test Harness • Не трогали Selenium ~5 лет… • Минорные изменения, легкий апдейт • Перешли на современные драйверы Selenium 92
  93. © 2019 CloudBees, Inc. All Rights Reserved. Jenkins-on-Jenkins. Сборка плагинов

    93 // Jenkinsfile buildPlugin() https://github.com/jenkins-infra/pipeline-library
  94. © 2019 CloudBees, Inc. All Rights Reserved. Jenkins-on-Jenkins. Сборка плагинов

    // Jenkinsfile buildPlugin(configurations: buildPlugin.recommendedConfigurations()) 94
  95. © 2019 CloudBees, Inc. All Rights Reserved. Jenkins-on-Jenkins. Сборка плагинов

    95
  96. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты 96 Инсталляторы Docker
  97. © 2019 CloudBees, Inc. All Rights Reserved. OracleJDK / OpenJDK

    Лицензионные соглашения... Новая политика в Oracle JDK 11+ https://www.oracle.com/technetwork/ja va/javase/overview/oracle-jdk-faqs.html Ограничения новых релизов OpenJDK 8 от Oracle 97
  98. © 2019 CloudBees, Inc. All Rights Reserved. OpenJDK Jigsaw Team:

    Собирайте OpenJDK сами Мы: • AdoptOpenJDK • RedHat JDK для CentOS • … Какой дистрибутив взять? 98 https://adoptopenjdk.net/
  99. © 2019 CloudBees, Inc. All Rights Reserved. 99

  100. © 2019 CloudBees, Inc. All Rights Reserved. Jenkins & Docker.

    Packaging https://hub.docker.com/r/jenkins/ AND https://hub.docker.com/r/jenkinsci 100
  101. © 2019 CloudBees, Inc. All Rights Reserved. Docker Packaging Базовый

    образ: https://hub.docker.com/_/openjdk/ 101
  102. © 2019 CloudBees, Inc. All Rights Reserved. Docker Packaging Базовый

    образ: https://hub.docker.com/_/openjdk/ • Поддерживается Docker, не Oracle • Отстает от релизов, особенно для EA • Нет образов для Arm & Co • Не рекомендовано OpenJDK Jigsaw Team • Непонятное будущее 102
  103. © 2019 CloudBees, Inc. All Rights Reserved. Сборка Дистрибутивы Юнит-тесты

    Статический анализ Интеграционные тесты 103
  104. © 2019 CloudBees, Inc. All Rights Reserved. Ожидания Image: https://www.kdnuggets.com/2016/10/big

    -data-science-expectation-reality.html 104
  105. © 2019 CloudBees, Inc. All Rights Reserved. Ожидания Image: https://www.kdnuggets.com/2016/10/big

    -data-science-expectation-reality.html Реальность 105
  106. © 2019 CloudBees, Inc. All Rights Reserved. • Jenkins работает

    на Java 11 • TLS 1.3 и улучшения “из коробки” • <1% распространение среди пользователей • Удалили экспериментальные опции (cgroups) • Обновили кодовую базу и зависимости Что получили? 106
  107. © 2019 CloudBees, Inc. All Rights Reserved. Чего не хватало?

    • Обновлённой Maven- экосистемы • Сканеров совместимости с Java 11 • Тулов для “правильного” апдейта зависимостей 107
  108. © 2019 CloudBees, Inc. All Rights Reserved. Чего не хватало?

    • Обновлённой Maven- экосистемы • Сканеров совместимости с Java 11 • Тулов для “правильного” апдейта зависимостей 108
  109. © 2019 CloudBees, Inc. All Rights Reserved. • Java 11

    - это серьёзно • Надо пробовать • Миграция возможна • Большая часть времени - CI и автотесты • Апдейт - Отличная возможность прочувствовать технический долг • Пробуйте тулы, если они есть Takeaways 109
  110. © 2019 CloudBees, Inc. All Rights Reserved. Contacts: E-mail: onenashev@cloudbees.com

    GitHub: oleg-nenashev Twitter: @oleg_nenashev ВОПРОСЫ? 110