Uploaded image for project: 'Maven Shade Plugin'
  1. Maven Shade Plugin
  2. MSHADE-105

Classes processed by the relocator still have references to the original classes in their constant pools

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 1.4
    • 1.6
    • None
    • Patch

    Description

      DefaultShader uses the ClassWriter(ClassReader, int) constructor instead of ClassWriter(int). According to the ASM Javadoc, this has the following effects:

      "- The constant pool from the original class is copied as is in the new class, which saves time. New constant pool entries will be added at the end if necessary, but unused constant pool entries won't be removed.

      • Methods that are not transformed are copied as is in the new class, directly from the original class bytecode (i.e. without emitting visit events for all the method instructions), which saves a lot of time. Untransformed methods are detected by the fact that the ClassReader receives MethodVisitor objects that come from a ClassWriter (and not from a custom ClassAdapter or any other ClassVisitor instance)."

      The second item is actually not applicable in the case of DefaultShader because the entire class needs to be transformed anyway. On the other hand, the first item implies that the constant pool of the transformed class will still have references to the original classes. This can be seen from the attached "javap.txt" file (produced by javap on a class relocated by maven-shade-plugin): the relocation adds new entries at the end of the constant pool, but the original entries are still present.

      Since the original entries are no longer referenced anywhere in the class, this has no consequences at runtime. However, some tools such as Felix' maven-bundle-plugin use the constant pool to determine the dependencies of a class. The effect is that if such a shaded JAR is embedded into a bundle using maven-bundle-plugin, it will generate spurious Import-Package instructions referring to the original package names. An example of this is described in AXIS2-5145.

      The solution to this problem is simply not to pass the ClassReader object to the ClassWriter constructor. With this change, the constant pool is properly cleaned up (see the attached "javap2.txt" file).

      Attachments

        1. javap.txt
          12 kB
          Andreas Veithen
        2. javap2.txt
          10 kB
          Andreas Veithen
        3. constant-pool.patch
          1 kB
          Andreas Veithen
        4. mshade-105-test.zip
          3 kB
          Andreas Veithen

        Issue Links

          Activity

            People

              olamy Olivier Lamy
              veithen Andreas Veithen
              Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: