[Git][java-team/bridge-method-injector][upstream] New upstream version 1.25

Tony Mancill (@tmancill) gitlab at salsa.debian.org
Sat Nov 19 19:01:57 GMT 2022



Tony Mancill pushed to branch upstream at Debian Java Maintainers / bridge-method-injector


Commits:
70be2d0d by tony mancill at 2022-11-17T19:45:02-08:00
New upstream version 1.25
- - - - -


17 changed files:

- .gitignore
- + .mvn/extensions.xml
- + .mvn/maven.config
- + Jenkinsfile
- src/site/apt/index.apt.vm → README.md
- annotation/pom.xml
- annotation/src/main/java/com/infradna/tool/bridge_method_injector/BridgeMethodsAdded.java
- annotation/src/main/java/com/infradna/tool/bridge_method_injector/WithBridgeMethods.java
- injector/pom.xml
- injector/src/main/java/com/infradna/tool/bridge_method_injector/MethodInjector.java
- injector/src/main/java/com/infradna/tool/bridge_method_injector/ProcessMojo.java
- injector/src/test/client/Main.java
- + injector/src/test/java/com/infradna/tool/bridge_method_injector/Junit4TestsRanTest.java
- injector/src/test/v1/Foo.java
- injector/src/test/v2/Foo.java
- pom.xml
- − src/site/site.xml


Changes:

=====================================
.gitignore
=====================================
@@ -1,4 +1,15 @@
 target
+
+# mvn hpi:run
+work
+
+# IntelliJ IDEA project files
 *.iml
-*.ipr
 *.iws
+*.ipr
+.idea
+
+# Eclipse project files
+.settings
+.classpath
+.project


=====================================
.mvn/extensions.xml
=====================================
@@ -0,0 +1,7 @@
+<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
+  <extension>
+    <groupId>io.jenkins.tools.incrementals</groupId>
+    <artifactId>git-changelist-maven-extension</artifactId>
+    <version>1.4</version>
+  </extension>
+</extensions>


=====================================
.mvn/maven.config
=====================================
@@ -0,0 +1,2 @@
+-Pconsume-incrementals
+-Pmight-produce-incrementals


=====================================
Jenkinsfile
=====================================
@@ -0,0 +1,10 @@
+/*
+ * While this is not a plugin, it is much simpler to reuse the pipeline code for CI. This allows for
+ * easy Linux/Windows testing and produces incrementals. The only feature that relates to plugins is
+ * allowing one to test against multiple Jenkins versions.
+ */
+buildPlugin(useContainerAgent: true, configurations: [
+  [ platform: 'linux', jdk: '11' ],
+  [ platform: 'windows', jdk: '11' ],
+  [ platform: 'linux', jdk: '17' ],
+])


=====================================
src/site/apt/index.apt.vm → README.md
=====================================
@@ -1,35 +1,35 @@
-What's this?
+# What's this?
 
-  When you are writing a library, there are various restrictions about the kind of changes you can make, in order to maintain binary compatibility.
+When you are writing a library, there are various restrictions about the kind of changes you can make, in order to maintain binary compatibility.
 
-  One such restriction is an inability to restrict the return type. Say in v1 of your library you had the following code:
+One such restriction is an inability to restrict the return type. Say in v1 of your library you had the following code:
 
-------------------------
+```java
 public Foo getFoo() {
     return new Foo();
 }
-------------------------
+```
 
-  In v2, say if you introduce a subtype of <<<Foo>>> called <<<FooSubType>>>, and you want to change the getFoo method to return <<<FooSubType>>>..
+In v2, say if you introduce a subtype of `Foo` called `FooSubType`, and you want to change the getFoo method to return `FooSubType`.
 
-------------------------
+```java
 public FooSubType getFoo() {
     return new FooSubType();
 }
-------------------------
+```
 
-  But if you do this, you break the binary compatibility. The clients need to be recompiled to be able to work with the new signature. This is where this bridge method injector can help. By adding an annotation like the following:
+But if you do this, you break the binary compatibility. The clients need to be recompiled to be able to work with the new signature. This is where this bridge method injector can help. By adding an annotation like the following:
 
-------------------------
+```java
 @WithBridgeMethods(Foo.class)
 public FooSubType getFoo() {
     return new FooSubType();
 }
-------------------------
+```
 
-  ... and running the bytecode post processor, your class file will get the additional "bridge methods." In pseudo-code, it'll look like this:
+... and running the bytecode post processor, your class file will get the additional "bridge methods." In pseudo-code, it'll look like this:
 
-------------------------
+```java
 // your original definition
 @WithBridgeMethods(Foo.class)
 public FooSubType getFoo() {
@@ -41,46 +41,46 @@ public Foo getFoo() {
     invokevirtual this.getFoo()LFooSubType;
     areturn
 }
-------------------------
+```
 
-  Such code isn't allowed in Java source files, but class files allow that. With this addition, existing clients will continue to function.
+Such code isn't allowed in Java source files, but class files allow that. With this addition, existing clients will continue to function.
 
-  In this way, you can evolve your classes more easily without breaking backward compatibility.
+In this way, you can evolve your classes more easily without breaking backward compatibility.
 
-Widening the return type
+# Widening the return type
 
-  In some cases, it's convenient to widen the return type of a method. As this is potentially a type-unsafe change
-  (as the callee can return a type that's not assignable to what the caller expects), so
-  you as a programmer explicitly need to tell us that you know what you are doing by adding
-  <<<castRequired>>> to the annotation.  For example, suppose that v1 had a method:
+In some cases, it's convenient to widen the return type of a method. As this is potentially a type-unsafe change
+(as the callee can return a type that's not assignable to what the caller expects), so
+you as a programmer explicitly need to tell us that you know what you are doing by adding
+`castRequired` to the annotation.  For example, suppose that v1 had a method:
 
-------------------------
+```java
 public <T extends FooSubType> createFoo(Class<T> clazz) {
     return clazz.newInstance();
 }
-------------------------
+```
 
-  and in v2 you wanted to widen this method to. Note that you can prove that this is still type-safe, while
-  your compile cannot:
+and in v2 you wanted to widen this method to. Note that you can prove that this is still type-safe, while
+your compile cannot:
 
-------------------------
+```java
 public <T extends Foo> createFoo(Class<T> clazz) {
     return clazz.newInstance();
 }
-------------------------
+```
 
-  The annotation to provide backwards compatibility would be:
+The annotation to provide backwards compatibility would be:
 
-------------------------
+```java
 @WithBridgeMethods(value=FooSubType.class, castRequired=true)
 public <T extends Foo> createFoo(Class<T> clazz) {
     return clazz.newInstance();
 }
-------------------------
+```
 
-  Running the bytecode post processor, the resulting class file will look like the following pseudo-code:
+Running the bytecode post processor, the resulting class file will look like the following pseudo-code:
 
-------------------------
+```java
 // your original definition
 @WithBridgeMethods(value=FooSubType.class, castRequired=true)
 public <T extends Foo> createFoo(Class<T> clazz) {
@@ -93,38 +93,38 @@ public FooSubType createFoo(Class clazz) {
     checkcast FooSubType
     areturn
 }
-------------------------
+```
 
-Bridge Methods and Interfaces
+# Bridge Methods and Interfaces
 
-  You can use <<<@WithBridgeMethods>>> with interfaces, too. However, making this work correctly is tricky,
-  as you have to ensure that bridge methods are implemented on all the classes that implement the interface,
-  for example by adding <<<@WithBridgeMethods>>> on every implementation of the method in question,
-  or by introducing a base class that provides a bridge method.
+You can use `@WithBridgeMethods` with interfaces, too. However, making this work correctly is tricky,
+as you have to ensure that bridge methods are implemented on all the classes that implement the interface,
+for example by adding `@WithBridgeMethods` on every implementation of the method in question,
+or by introducing a base class that provides a bridge method.
 
-Integration into Your Build
+# Integration into Your Build
 
-  Add the following dependency in your POM. (This dependency is not needed at runtime, but it is necessary
-  for compilation of source code that transitively depend on this, so it is the simplest to just treat
-  this like a regular library dependency)
+Add the following dependency in your POM. (This dependency is not needed at runtime, but it is necessary
+for compilation of source code that transitively depend on this, so it is the simplest to just treat
+this like a regular library dependency)
 
-------------------------
+```xml
     <dependency>
       <groupId>com.infradna.tool</groupId>
       <artifactId>bridge-method-annotation</artifactId>
-      <version>1.12</version>
+      <version>1.24</version>
     </dependency>
-------------------------
+```
 
   Then put the following fragment in your build to have the byte-code post processor kick in to inject the necessary bridge methods.
 
-------------------------
+```xml
   <build>
     <plugins>
       <plugin>
         <groupId>com.infradna.tool</groupId>
         <artifactId>bridge-method-injector</artifactId>
-        <version>1.4</version>
+        <version>1.24</version>
         <executions>
           <execution>
             <goals>
@@ -135,6 +135,5 @@ Integration into Your Build
       </plugin>
     </plugins>
   </build>
-------------------------
+```
 
-  The artifacts are deployed to {{{http://maven.dyndns.org/2/com/infradna/tool/bridge-method-injector/}java.net Maven2 repository}}.


=====================================
annotation/pom.xml
=====================================
@@ -1,10 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <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/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>com.infradna.tool</groupId>
     <artifactId>bridge-method-injector-parent</artifactId>
-    <version>1.23</version>
-    <relativePath>../pom.xml</relativePath>
+    <version>1.25</version>
   </parent>
   <artifactId>bridge-method-annotation</artifactId>
   <name>Bridge method injection annotations</name>
@@ -13,14 +13,7 @@
     <dependency>
       <groupId>org.jenkins-ci</groupId>
       <artifactId>annotation-indexer</artifactId>
-      <version>1.15</version>
+      <version>1.16</version>
     </dependency>
   </dependencies>
-  
-  <repositories>
-      <repository>
-          <id>Jenkins-CI</id>
-          <url>http://repo.jenkins-ci.org/releases/</url>
-      </repository>
-  </repositories>
 </project>


=====================================
annotation/src/main/java/com/infradna/tool/bridge_method_injector/BridgeMethodsAdded.java
=====================================
@@ -23,12 +23,11 @@
  */
 package com.infradna.tool.bridge_method_injector;
 
+import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
 /**
  * This annotation is added after the class transformation to indicate that
  * the class has already been processed by bridge method injector.
@@ -38,7 +37,7 @@ import static java.lang.annotation.RetentionPolicy.*;
  *
  * @author Kohsuke Kawaguchi
  */
- at Retention(CLASS)
- at Target(TYPE)
+ at Retention(RetentionPolicy.CLASS)
+ at Target(ElementType.TYPE)
 public @interface BridgeMethodsAdded {
 }


=====================================
annotation/src/main/java/com/infradna/tool/bridge_method_injector/WithBridgeMethods.java
=====================================
@@ -26,12 +26,11 @@ package com.infradna.tool.bridge_method_injector;
 import org.jvnet.hudson.annotation_indexer.Indexed;
 
 import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.CLASS;
-
 /**
  * Request that bridge methods of the same name and same arguments be generated
  * with each specified type as the return type. This helps you maintain binary compatibility
@@ -103,8 +102,8 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
  *
  * @author Kohsuke Kawaguchi
  */
- at Retention(CLASS)
- at Target(METHOD)
+ at Retention(RetentionPolicy.CLASS)
+ at Target(ElementType.METHOD)
 @Documented
 @Indexed
 public @interface WithBridgeMethods {


=====================================
injector/pom.xml
=====================================
@@ -1,10 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <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/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>com.infradna.tool</groupId>
     <artifactId>bridge-method-injector-parent</artifactId>
-    <version>1.23</version>
-    <relativePath>../pom.xml</relativePath>
+    <version>1.25</version>
   </parent>
   <artifactId>bridge-method-injector</artifactId>
   <packaging>maven-plugin</packaging>
@@ -13,7 +13,8 @@
   <description>Evolve your classes without breaking compatibility</description>
 
   <properties>
-    <asm.version>9.2</asm.version>
+    <asm.version>9.4</asm.version>
+    <maven-plugin-tools.version>3.7.0</maven-plugin-tools.version>
   </properties>
 
   <build>
@@ -21,27 +22,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-plugin-plugin</artifactId>
-        <version>3.6.0</version>
-      </plugin>
-      <plugin>
-        <artifactId>maven-compiler-plugin</artifactId>
-	<version>3.8.1</version>
-        <configuration>
-          <source>1.8</source>
-          <target>1.8</target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-release-plugin</artifactId>
-        <version>2.0</version>
-        <dependencies>
-          <dependency>
-            <groupId>org.apache.maven.scm</groupId>
-            <artifactId>maven-scm-provider-gitexe</artifactId>
-            <version>1.2</version>
-          </dependency>
-        </dependencies>
+        <version>${maven-plugin-tools.version}</version>
       </plugin>
       <plugin>
         <artifactId>maven-antrun-plugin</artifactId>
@@ -52,7 +33,7 @@
             </goals>
             <phase>test</phase>
             <configuration>
-              <tasks>
+              <target>
                 <delete dir="target/test-classes" />
                 <mkdir dir="target/test-classes/v1" />
                 <mkdir dir="target/test-classes/v2" />
@@ -60,9 +41,10 @@
                 <mkdir dir="target/test-classes/synthetics" />
 
                 <!-- basic sanity. unmodified client and v1 should work as expected -->
-                <javac source="8" target="8" srcdir="src/test/v1" destdir="target/test-classes/v1" />
-                <javac source="8" target="8" srcdir="src/test/client" destdir="target/test-classes/client" classpath="target/test-classes/v1" />
-                <java classname="Main" args="foo" failonerror="true">
+                <javac release="${maven.compiler.release}" srcdir="src/test/v1" destdir="target/test-classes/v1" includeantruntime="false" />
+                <javac release="${maven.compiler.release}" srcdir="src/test/client" destdir="target/test-classes/client" classpath="target/test-classes/v1" includeantruntime="false" />
+                <java classname="Main" failonerror="true">
+                  <arg value="foo" />
                   <classpath>
                     <pathelement path="target/test-classes/v1" />
                     <pathelement path="target/test-classes/client" />
@@ -70,7 +52,7 @@
                 </java>
 
                 <!-- compile v2 -->
-                <javac source="8" target="8" srcdir="src/test/v2" destdir="target/test-classes/v2" classpath="${maven.compile.classpath}">
+                <javac release="${maven.compiler.release}" srcdir="src/test/v2" destdir="target/test-classes/v2" classpath="${maven.compile.classpath}" includeantruntime="false">
                   <compilerarg value="-XprintProcessorInfo" />
                   <classpath>
                     <pathelement path="target/classes" />
@@ -79,12 +61,14 @@
                 </javac>
 
                 <!-- post process v2 -->
-                <java classname="com.infradna.tool.bridge_method_injector.MethodInjector" args="${project.basedir}/target/test-classes/v2" failonerror="true">
+                <java classname="com.infradna.tool.bridge_method_injector.MethodInjector" failonerror="true">
+                  <arg value="${project.basedir}/target/test-classes/v2" />
                   <classpath refid="maven.compile.classpath" />
                 </java>
 
                 <!-- verify that unmodified client code continue to work with v2 binary -->
-                <java classname="Main" args="bar" failonerror="true">
+                <java classname="Main" failonerror="true">
+                  <arg value="bar" />
                   <classpath>
                     <pathelement path="target/test-classes/v2" />
                     <pathelement path="target/test-classes/client" />
@@ -92,7 +76,7 @@
                 </java>
 
                 <!-- compile synthetics -->
-                <javac source="8" target="8" srcdir="src/test/synthetics" destdir="target/test-classes/synthetics" classpath="${maven.compile.classpath}">
+                <javac release="${maven.compiler.release}" srcdir="src/test/synthetics" destdir="target/test-classes/synthetics" classpath="${maven.compile.classpath}" includeantruntime="false">
                   <compilerarg value="-XprintProcessorInfo" />
                   <classpath>
                     <pathelement path="target/classes" />
@@ -101,75 +85,52 @@
                 </javac>
 
                 <!-- post process synthetics -->
-                <java classname="com.infradna.tool.bridge_method_injector.MethodInjector" args="${project.basedir}/target/test-classes/synthetics" failonerror="true">
+                <java classname="com.infradna.tool.bridge_method_injector.MethodInjector" failonerror="true">
+                  <arg value="${project.basedir}/target/test-classes/synthetics" />
                   <classpath refid="maven.compile.classpath" />
                 </java>
 
                 <!-- was testing source compatibility, but with widening change it won't work anymore -->
                 <!--
                 <mkdir dir="target/test-classes/client-on-v2" />
-                <javac source="8" target="8" srcdir="src/test/client" destdir="target/test-classes/client-on-v2">
+                <javac release="${maven.compiler.release}" srcdir="src/test/client" destdir="target/test-classes/client-on-v2" includeantruntime="false">
                   <classpath>
                     <pathelement path="target/test-classes/v2" />
                   </classpath>
                 </javac>
-                <java classname="Main" args="bar" failonerror="true">
+                <java classname="Main" failonerror="true">
+                  <arg value="bar" />
                   <classpath>
                     <pathelement path="target/test-classes/v2" />
                     <pathelement path="target/test-classes/client-on-v2" />
                   </classpath>
                 </java>
                 -->
-              </tasks>
+              </target>
             </configuration>
           </execution>
         </executions>
-        <dependencies>
-          <dependency>
-            <groupId>com.sun</groupId>
-            <artifactId>tools</artifactId>
-            <version>1.8</version>
-            <scope>system</scope>
-            <systemPath>${java.home}/../lib/tools.jar</systemPath>
-          </dependency>
-        </dependencies>
       </plugin>
     </plugins>
-    <extensions>
-      <extension>
-        <groupId>org.jvnet.wagon-svn</groupId>
-        <artifactId>wagon-svn</artifactId>
-        <version>1.9</version>
-      </extension>
-    </extensions>
   </build>
 
-  <scm>
-    <connection>scm:git:git at github.com:infradna/bridge-method-injector.git</connection>
-    <tag>bridge-method-injector-parent-1.23</tag>
-  </scm>
-
-  <developers>
-    <developer>
-      <id>kohsuke</id>
-      <name>Kohsuke Kawaguchi</name>
-    </developer>
-  </developers>
-
-  <licenses>
-    <license>
-      <name>MIT License</name>
-      <distribution>repository</distribution>
-      <url>http://www.opensource.org/licenses/mit-license.php</url>
-    </license>
-  </licenses>
-
   <dependencies>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>bridge-method-annotation</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>com.github.spotbugs</groupId>
+      <artifactId>spotbugs-annotations</artifactId>
+      <optional>true</optional>
+      <exclusions>
+        <exclusion>
+          <groupId>com.google.code.findbugs</groupId>
+          <artifactId>jsr305</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
     <dependency>
       <groupId>org.ow2.asm</groupId>
       <artifactId>asm</artifactId>
@@ -180,17 +141,23 @@
       <artifactId>asm-commons</artifactId>
       <version>${asm.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>3.8.6</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.plugin-tools</groupId>
+      <artifactId>maven-plugin-annotations</artifactId>
+      <version>${maven-plugin-tools.version}</version>
+      <scope>provided</scope>
+    </dependency>
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.13.1</version>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-plugin-api</artifactId>
-      <version>2.0.1</version>
-    </dependency>
   </dependencies>
   
 </project>


=====================================
injector/src/main/java/com/infradna/tool/bridge_method_injector/MethodInjector.java
=====================================
@@ -28,7 +28,6 @@ import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
 import static org.objectweb.asm.Opcodes.ACC_BRIDGE;
 import static org.objectweb.asm.Opcodes.ACC_STATIC;
 import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
-import static org.objectweb.asm.Opcodes.ALOAD;
 import static org.objectweb.asm.Opcodes.ILOAD;
 import static org.objectweb.asm.Opcodes.INVOKESTATIC;
 import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
@@ -44,6 +43,8 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
 import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
@@ -61,63 +62,41 @@ import org.objectweb.asm.commons.GeneratorAdapter;
 public class MethodInjector {
     public void handleRecursively(File f) throws IOException {
         if (f.isDirectory()) {
-            for (File c : f.listFiles())
-                handleRecursively(c);
-        } else if (f.getName().endsWith(".class"))
+            File[] files = f.listFiles();
+            if (files != null) {
+                for (File c : files) {
+                    handleRecursively(c);
+                }
+            }
+        } else if (f.getName().endsWith(".class")) {
             handle(f);
+        }
     }
 
     public void handle(File classFile) throws IOException {
-        FileInputStream in = new FileInputStream(classFile);
         byte[] image;
-        try {
-            ClassReader cr = new ClassReader(new BufferedInputStream(in));
-            /*
-                working around JENKINS-22525 by not passing in 'cr'
-
-                Javac as of 6u31 seems to produce duplicate constant pool entries in some cases.
-                When such a class is transformed through ClassReader -> ClassWriter, it creates
-                a class file where reference sites to those duplicate entries get reshuffled
-                (for example, say #15 and #30 are the duplicate entries, and after a transformation
-                some references that used to use #15 now refers to #30, and vice versa.)
-
-                This is because ClassVisitor interfaces passes around strings, and
-                ClassWriter looks up its constant pool to assign its index.
-
-                For whatever reasons, this triggers "incompatible InnerClasses attribute" problem
-                in IBM J9VM (observed with R26_Java726_SR7_20140409_1418_B195732), while
-                it is happy with the original class file.
-
-                It appears that this rare situation of having duplicate entries in constant pools
-                and have various references use them in a certain way induces this J9 VM bug.
-
-                To work around this problem, we make ASM rebuild the constant pool from scratch,
-                which totally eliminates any duplicate entries.
-             */
-            ClassWriter cw = new ClassWriter(/*cr,*/COMPUTE_MAXS);
+        try (FileInputStream in = new FileInputStream(classFile); BufferedInputStream bis = new BufferedInputStream(in)) {
+            ClassReader cr = new ClassReader(bis);
+            ClassWriter cw = new ClassWriter(cr,COMPUTE_MAXS);
             cr.accept(new Transformer(new ClassAnnotationInjectorImpl(cw)),0);
             image = cw.toByteArray();
-        } catch (AlreadyUpToDate _) {
+        } catch (AlreadyUpToDate unused) {
             // no need to process this class. it's already up-to-date.
             return;
-        } catch (IOException e) {
-            throw (IOException)new IOException("Failed to process "+classFile).initCause(e);
-        } catch (RuntimeException e) {
-            throw (IOException)new IOException("Failed to process "+classFile).initCause(e);
-        } finally {
-            in.close();
+        } catch (IOException | RuntimeException e) {
+            throw new IOException("Failed to process " + classFile, e);
         }
 
         // write it back
-        FileOutputStream out = new FileOutputStream(classFile);
-        out.write(image);
-        out.close();
+        try (FileOutputStream out = new FileOutputStream(classFile)) {
+            out.write(image);
+        }
     }
 
     /**
      * Thrown to indicate that there's no need to re-process this class file.
      */
-    class AlreadyUpToDate extends RuntimeException {
+    static class AlreadyUpToDate extends RuntimeException {
       private static final long serialVersionUID = 1L;
     }
 
@@ -136,7 +115,7 @@ public class MethodInjector {
     private static class WithBridgeMethodsAnnotationVisitor extends AnnotationVisitor {
       protected boolean castRequired = false;
       protected String adapterMethod = null;
-      protected List<Type> types = new ArrayList<Type>();
+      protected final List<Type> types = new ArrayList<>();
       
       public WithBridgeMethodsAnnotationVisitor(AnnotationVisitor av) {
         super(Opcodes.ASM9, av);
@@ -146,6 +125,7 @@ public class MethodInjector {
       public AnnotationVisitor visitArray(String name) {
         return new AnnotationVisitor(Opcodes.ASM9, super.visitArray(name)) {
            
+            @Override
             public void visit(String name, Object value) {
                 if (value instanceof Type) {
                   // assume this is a member of the array of classes named "value" in WithBridgeMethods
@@ -169,12 +149,12 @@ public class MethodInjector {
       }
     }
 
-    class Transformer extends ClassVisitor {
+    static class Transformer extends ClassVisitor {
         private String internalClassName;
         /**
          * Synthetic methods to be generated.
          */
-        private final List<SyntheticMethod> syntheticMethods = new ArrayList<SyntheticMethod>();
+        private final List<SyntheticMethod> syntheticMethods = new ArrayList<>();
 
         class SyntheticMethod {
             final int access;
@@ -239,11 +219,11 @@ public class MethodInjector {
                         sz += p.getSize();
                     }
                     mv.visitMethodInsn(
-                      isStatic ? INVOKESTATIC : INVOKEVIRTUAL,internalClassName,name,desc);
+                      isStatic ? INVOKESTATIC : INVOKEVIRTUAL,internalClassName,name,desc,false);
                     if (hasAdapterMethod()) {
                         insertAdapterMethod(ga);
                     } else
-                    if (castRequired) {
+                    if (castRequired || returnType.equals(Type.VOID_TYPE)) {
                         ga.unbox(returnType);
                     } else {
                         ga.box(originalReturnType);
@@ -251,6 +231,8 @@ public class MethodInjector {
                     if (returnType.equals(Type.VOID_TYPE) || returnType.getClassName().equals("java.lang.Void")) {
                         // bridge to void, which means disregard the return value from the original method
                         switch (originalReturnType.getSize()) {
+                        case 0:
+                            throw new IllegalArgumentException("Cannot bridge " + name + " from void to void; did you mean to use a different type?");
                         case 1:
                             mv.visitInsn(POP);
                             break;
@@ -278,7 +260,7 @@ public class MethodInjector {
                                 Type.getType(Object.class), // return type
                                 originalReturnType,
                                 Type.getType(Class.class)
-                        ));
+                        ), false);
                 ga.unbox(returnType);
             }
         }
@@ -295,8 +277,9 @@ public class MethodInjector {
 
         @Override
         public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            if (desc.equals(SYNTHETIC_METHODS_ADDED))
+            if (desc.equals(SYNTHETIC_METHODS_ADDED)) {
                 throw new AlreadyUpToDate();    // no need to process this class
+            }
             return super.visitAnnotation(desc, visible);
         }
 
@@ -310,18 +293,20 @@ public class MethodInjector {
                 @Override
                 public AnnotationVisitor visitAnnotation(String adesc, boolean visible) {
                     AnnotationVisitor av = super.visitAnnotation(adesc, visible);
-                    if (adesc.equals(WITH_SYNTHETIC_METHODS) && (access & ACC_SYNTHETIC) == 0)
+                    if (adesc.equals(WITH_SYNTHETIC_METHODS) && (access & ACC_SYNTHETIC) == 0) {
                         return new WithBridgeMethodsAnnotationVisitor(av) {
                         
                             @Override
                             public void visitEnd() {
                                 super.visitEnd(); 
-                                for (Type type : this.types)
+                                for (Type type : this.types) {
                                     syntheticMethods.add(new SyntheticMethod(
                                          access,name,mdesc,signature,exceptions,type, this.castRequired, this.adapterMethod
                                     ));
+                                }
                             }
                         };
+                    }
                     return av;
                 }
             };
@@ -332,12 +317,14 @@ public class MethodInjector {
          */
         @Override
         public void visitEnd() {
-            for (SyntheticMethod m : syntheticMethods)
+            for (SyntheticMethod m : syntheticMethods) {
                 m.inject(cv);
+            }
             super.visitEnd();
         }
     }
 
+    @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "user-provided value for running the program")
     public static void main(String[] args) throws IOException {
         MethodInjector mi = new MethodInjector();
         for (String a : args) {


=====================================
injector/src/main/java/com/infradna/tool/bridge_method_injector/ProcessMojo.java
=====================================
@@ -23,9 +23,14 @@
  */
 package com.infradna.tool.bridge_method_injector;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
 
 import java.io.File;
 import java.io.IOException;
@@ -35,21 +40,20 @@ import org.jvnet.hudson.annotation_indexer.Index;
 
 /**
  * @author Kohsuke Kawaguchi
- * @goal process
- * @phase process-classes
- * @requiresDependencyResolution runtime
- * @threadSafe
  */
+ at Mojo(name = "process", requiresDependencyResolution = ResolutionScope.RUNTIME, defaultPhase = LifecyclePhase.PROCESS_CLASSES, threadSafe = true)
 public class ProcessMojo extends AbstractMojo {
     /**
      * The directory containing generated classes.
-     *
-     * @parameter expression="${project.build.outputDirectory}"
-     * @required
      */
+    @Parameter(defaultValue = "${project.build.outputDirectory}", required = true)
     private File classesDirectory;
 
-    public void execute() throws MojoExecutionException, MojoFailureException {
+    @Override
+    @SuppressFBWarnings(
+            value = {"DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED", "PATH_TRAVERSAL_IN"},
+            justification = "irrelevant without SecurityManager; user-provided value for running the program")
+    public void execute() throws MojoExecutionException {
         try {
             for (String line : Index.listClassNames(WithBridgeMethods.class, new URLClassLoader(new URL[] {classesDirectory.toURI().toURL()}, ClassLoader.getSystemClassLoader().getParent()))) {
                 File classFile = new File(classesDirectory,line.replace('.','/')+".class");


=====================================
injector/src/test/client/Main.java
=====================================
@@ -1,8 +1,23 @@
 public class Main {
     public static void main(String[] args) throws Exception {
         // invocation of void method. verify that it runs without error
+
+        Foo.toggle = false;
         Foo.hello();
+        assertEquals(true, Foo.toggle);
+
+        Foo.toggle = false;
         Foo.hello2();
+        assertEquals(true, Foo.toggle);
+
+        Foo.toggle = false;
+        new Foo().hello3();
+        assertEquals(true, Foo.toggle);
+
+        Foo.toggle = false;
+        new Foo().hello4();
+        assertEquals(true, Foo.toggle);
+
         Foo.unbox();
         Foo.box();
 


=====================================
injector/src/test/java/com/infradna/tool/bridge_method_injector/Junit4TestsRanTest.java
=====================================
@@ -0,0 +1,14 @@
+package com.infradna.tool.bridge_method_injector;
+
+import org.junit.Test;
+
+public class Junit4TestsRanTest {
+
+    @Test
+    public void anything() {
+        /*
+         * Intentionally blank. We just want a test that runs with JUnit so that buildPlugin() works
+         * in the Jenkinsfile.
+         */
+    }
+}


=====================================
injector/src/test/v1/Foo.java
=====================================
@@ -21,9 +21,23 @@ public class Foo implements IFoo {
       return clazz.cast("foo");
     }
 
-    public static void hello() {}
+    static boolean toggle;
 
-    public static void hello2() {}
+    public static void hello() {
+        toggle = true;
+    }
+
+    public static void hello2() {
+        toggle = true;
+    }
+
+    public void hello3() {
+        toggle = true;
+    }
+
+    public void hello4() {
+        toggle = true;
+    }
     
     public static int unbox() {return Integer.MIN_VALUE;}
     


=====================================
injector/src/test/v2/Foo.java
=====================================
@@ -24,15 +24,31 @@ public class Foo implements IFoo {
       return clazz.cast("bar");
     }
 
+    static boolean toggle;
+
     @WithBridgeMethods(void.class)
     public static boolean hello() {
+        toggle = true;
         return true;
     }
 
     @WithBridgeMethods(void.class)
     public static String hello2() {
+        toggle = true;
         return "hello2";
     }
+
+    @WithBridgeMethods(void.class)
+    public boolean hello3() {
+        toggle = true;
+        return true;
+    }
+
+    @WithBridgeMethods(void.class)
+    public String hello4() {
+        toggle = true;
+        return "hello4";
+    }
     
     @WithBridgeMethods(value=int.class, castRequired=true)
     public static Integer unbox() {


=====================================
pom.xml
=====================================
@@ -1,65 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <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/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
+  <parent>
+    <groupId>org.jenkins-ci</groupId>
+    <artifactId>jenkins</artifactId>
+    <version>1.91</version>
+    <relativePath />
+  </parent>
+
   <groupId>com.infradna.tool</groupId>
   <artifactId>bridge-method-injector-parent</artifactId>
-  <version>1.23</version>
+  <version>1.25</version>
   <packaging>pom</packaging>
 
   <name>Bridge Method Injection Parent POM</name>
   <description>Evolve your classes without breaking compatibility</description>
-  <url>http://bridge-method-injector.infradna.com/</url>
+  <url>https://github.com/jenkinsci/bridge-method-injector</url>
 
   <modules>
     <module>annotation</module>
     <module>injector</module>
   </modules>
 
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-compiler-plugin</artifactId>
-	<version>3.8.1</version>
-        <configuration>
-          <source>1.8</source>
-          <target>1.8</target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-release-plugin</artifactId>
-        <version>2.5.1</version>
-        <configuration>
-          <releaseProfiles>release</releaseProfiles>
-        </configuration>
-        <dependencies>
-          <dependency>
-            <groupId>org.apache.maven.scm</groupId>
-            <artifactId>maven-scm-provider-gitexe</artifactId>
-            <version>1.2</version>
-          </dependency>
-        </dependencies>
-      </plugin>
-      <plugin>
-        <groupId>org.sonatype.plugins</groupId>
-        <artifactId>nexus-staging-maven-plugin</artifactId>
-        <version>1.6.2</version>
-        <extensions>true</extensions>
-        <configuration>
-          <serverId>sonatype-nexus-staging</serverId>
-          <nexusUrl>https://oss.sonatype.org/</nexusUrl>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <version>2.7</version>
-        <configuration>
-          <additionalparam>-Xdoclint:none</additionalparam>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+  <properties>
+    <revision>1.25</revision>
+    <changelist>-SNAPSHOT</changelist>
+    <gitHubRepo>jenkinsci/bridge-method-injector</gitHubRepo>
+  </properties>
 
   <repositories>
     <repository>
@@ -68,10 +36,18 @@
     </repository>
   </repositories>
 
-  <scm>
-    <connection>scm:git:git at github.com:infradna/bridge-method-injector.git</connection>
-    <url>https://github.com/infradna/bridge-method-injector</url>
-    <tag>bridge-method-injector-parent-1.23</tag>
+  <pluginRepositories>
+    <pluginRepository>
+      <id>repo.jenkins-ci.org</id>
+      <url>https://repo.jenkins-ci.org/public/</url>
+    </pluginRepository>
+  </pluginRepositories>
+
+  <scm child.scm.connection.inherit.append.path="false" child.scm.developerConnection.inherit.append.path="false" child.scm.url.inherit.append.path="false">
+    <connection>scm:git:https://github.com/${gitHubRepo}.git</connection>
+    <developerConnection>scm:git:git at github.com:${gitHubRepo}.git</developerConnection>
+    <url>https://github.com/${gitHubRepo}</url>
+    <tag>bridge-method-injector-parent-1.25</tag>
   </scm>
 
   <developers>
@@ -85,55 +61,7 @@
     <license>
       <name>MIT License</name>
       <distribution>repository</distribution>
-      <url>http://www.opensource.org/licenses/mit-license.php</url>
+      <url>https://opensource.org/licenses/MIT</url>
     </license>
   </licenses>
-
-  <distributionManagement>
-    <repository>
-      <id>sonatype-nexus-staging</id>
-      <name>Nexus Release Repository</name>
-      <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
-    </repository>
-    <snapshotRepository>
-      <id>sonatype-nexus-snapshots</id>
-      <name>Sonatype Nexus Snapshots</name>
-      <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
-    </snapshotRepository>
-  </distributionManagement>
-
-
-  <reporting>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <configuration>
-          <aggregate>true</aggregate>
-        </configuration>
-      </plugin>
-    </plugins>
-  </reporting>
-
-  <profiles>
-    <profile>
-      <id>release</id>
-      <build>
-        <plugins>
-          <plugin>
-            <artifactId>maven-gpg-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>sign-artifacts</id>
-                <phase>verify</phase>
-                <goals>
-                  <goal>sign</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
 </project>


=====================================
src/site/site.xml deleted
=====================================
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<project name="Bridge Method Injector">
-  <bannerLeft>
-    <name>Bridge Method Injector</name>
-    <href>http://bridge-method-injector.infradna.com/</href>
-  </bannerLeft>
-  <skin>
-    <groupId>org.kohsuke</groupId>
-    <artifactId>maven-skin</artifactId>
-    <version>1.1</version>
-  </skin>
-  <!--<bannerRight>-->
-    <!--<src>http://maven.apache.org/images/maven-small.gif</src>-->
-  <!--</bannerRight>-->
-  <body>
-    <menu name="Bridge Method Injector">
-      <item name="Introduction" href="index.html"/>
-      <!--item name="User Guide" href="user-guide.html"/-->
-      <item name="Download" href="http://maven.dyndns.org/2/com/infradna/tool/bridge-method-injector/"/>
-    </menu>
-
-    <menu name="References">
-      <item name="Javadoc" href="apidocs/index.html"/>
-    </menu>
-
-    <menu ref="reports"/>
-  </body>
-</project>
-



View it on GitLab: https://salsa.debian.org/java-team/bridge-method-injector/-/commit/70be2d0d3bcfc802c3194a147e5fa5893e9a1812

-- 
View it on GitLab: https://salsa.debian.org/java-team/bridge-method-injector/-/commit/70be2d0d3bcfc802c3194a147e5fa5893e9a1812
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20221119/5f91eaa5/attachment.htm>


More information about the pkg-java-commits mailing list