<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Duncan,</p>
    <p>In this case the functional interface QueryInterface is being
      generated because a field in the enclosing struct has a field with
      a function pointer type. QueryInterface_UP$MH is a constant
      required by the implementation of that interface.<br>
    </p>
    <p>While I think your solution could fix the immediate issue you're
      having, we recently moved constants like QueryInterface_UP$MH to
      all be generated in the constant support files [1]. I think that
      is long term a better solution, since it takes the proper care to
      make sure the source files don't get too large.<br>
    </p>
    <p>With that patch, it would however still be dicey to manually
      strip the compiled classes from a jar though, since there would
      still be a reference to the class from the constants file. So, if
      another constant in the same file was accessed, the same issue
      would occur. Unless -Djextract.constants.per.class=0 is used as
      well, so that each constant class has only 1 constant.</p>
    <p> I think stripping classes from a jar will always be risky, since
      it is done without the knowledge of jextract. We have the <font face="monospace">--include-*</font> options as a supported way
      to do filtering in jextract. I think adding an <font face="monospace">--include-*</font> option for filtering out
      functional interface is reasonable as well. If you know you are
      never going to use the generated interface, it should be possible
      to filter it out (and all the constants it depends on). I've
      filled an issue for this:
      <a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/CODETOOLS-7903456">https://bugs.openjdk.org/browse/CODETOOLS-7903456</a><br>
    </p>
    <p>Jorn<br>
      <br>
      [1] : <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jextract/pull/117">https://github.com/openjdk/jextract/pull/117</a><br>
    </p>
    <div class="moz-cite-prefix">On 08/04/2023 19:10, Duncan Gittins
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CABOqcFu-VPaQ+KdEh=YtTDEOxdwLt+K9Jf1gF+aYDME23dX6pQ@mail.gmail.com">
      
      <div dir="ltr">Jorn
        <div><br>
        </div>
        <div>Thanks everyone for the effort on this. Its been a while
          since I've built my own jextract v20 so your build has given
          me more recent changes.
          <div><br>
          </div>
          <div>Apologies if this is covered in previous trails: I have
            run into an issue related to the way some performance
            changes were implemented in upcall stub generation. The
            generated code has introduced new class loader dependencies
            for Windows COM interfaces. For example using
            IShellLinkWVtbl gives rise to many interfaces such as
            IShellLinkWVtbl$QueryInterface.  </div>
          <div><br>
          </div>
          <div>All is fine if use new jextract and perform my tests with
            generated file.  My arguments for jextract are: </div>
          <div>
            <div>    --source  -lshell32 -t duncan.win.shell --output
              source\duncan.win\java headers\Shell32.h </div>
            <div>where Shell32.h is just: </div>
            <div>     #include <shlobj_core.h></div>
            <div><br>
            </div>
          </div>
          <div>However I've noticed the new jextract generated code has
            new class dependencies. I lookup COM objects via
            IUnknown$QueryInterface and never call the duplicate version
            like IShellLinkWVtbl$QueryInterface so I've been striping
            these similar and un-used classes from my jars. <br>
          </div>
          <div><br>
          </div>
          <div>In the old code generation, IShellLinkWVtbl was
            independent of IShellLinkWVtbl$QueryInterface and all other
            IXYZ COM interfaces.<br>
          </div>
          <div><br>
          </div>
          <div>The new generated code of IShellLinkWVtbl.java references
            IShellLinkWVtbl$QueryInterface.class. Similarly every vtable
            class (eg IUnknown / IPersistFile etc) depends now on every
            interface class file of every COM interface (AddRef /
            Release / etc) it supports because of the new xyz_UP$MH
            fields:</div>
          <div>
            <div><br>
            </div>
          </div>
          <div>
            <div>    Exception java.lang.NoClassDefFoundError:
              duncan/win/shell/IShellLinkWVtbl$QueryInterface<br>
                   |        at IShellLinkWVtbl.<clinit>
              (IShellLinkWVtbl.java:75)<br>
            </div>
            <div><br>
            </div>
            <div>
              <div>Here is the snippet of new code which shows the new
                upcallHandle which means every vtable.class requires all
                com .class files. I am hoping that this can be resolved
                easily simply by generating the declaration of
                QueryInterface_UP$MH inside interface
                IShellLinkWVtbl$QueryInterface rather than into the
                parent class IShellLinkWVtbl. This would avoid a large
                number of .class files being read when referencing a
                vtable class:</div>
            </div>
            <div><br>
            </div>
          </div>
          <div>    public class IShellLinkWVtbl {<br>
          </div>
          <div>     ... </div>
          <div>      static final MethodHandle QueryInterface_UP$MH =
            RuntimeHelper.upcallHandle(QueryInterface.class, "apply",
            IShellLinkWVtbl.QueryInterface_UP$FUNC);</div>
          <div>    ...<br>
                    /** HRESULT (*QueryInterface)(IShellLinkW*,const
            IID*,void**); */<br>
                    public interface QueryInterface { </div>
          <div>            // 
            UP$MH should be here?<br>
                        int apply(java.lang.foreign.MemorySegment _x0,
            java.lang.foreign.MemorySegment _x1,
            java.lang.foreign.MemorySegment _x2);<br>
                        static MemorySegment allocate(QueryInterface fi,
            SegmentScope scope) {<br>
                        return
            RuntimeHelper.upcallStub(IShellLinkWVtbl.QueryInterface_UP$MH,
            fi, IShellLinkWVtbl.QueryInterface$FUNC, scope);<br>
                    }<br>
                  ...<br>
                }<br>
          </div>
          <div><br>
          </div>
          <div>Kind regards</div>
          <div><br>
          </div>
          <div>Duncan</div>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Fri, 7 Apr 2023 at 18:34,
          Jorn Vernee <<a href="mailto:jorn.vernee@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">jorn.vernee@oracle.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
          0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
          <br>
          Jextract 20 binaries are now available at: <a href="https://urldefense.com/v3/__https://jdk.java.net/jextract/__;!!ACWV5N9M2RV99hQ!Lub79JM1QWad74DQ066IIkIBcFwi4DYJXQssC4oVgEC8gOf4yh9sd209Pz_Tt0tFZjEMv4eIkP5e9hb0t0W-h2P5ww$" rel="noreferrer" target="_blank" moz-do-not-send="true">https://jdk.java.net/jextract/</a><br>
          <br>
          This version of jextract targets the foreign function and
          memory access <br>
          API in Java 20, which was released recently as well [1]<br>
          <br>
          The existing binaries of jextract 19, which target Java 19,
          are still <br>
          available through a link under the "Other versions" section on
          the <br>
          jextract download page linked above.<br>
          <br>
          Jorn<br>
          <br>
          [1]: <a href="https://urldefense.com/v3/__https://jdk.java.net/20/__;!!ACWV5N9M2RV99hQ!Lub79JM1QWad74DQ066IIkIBcFwi4DYJXQssC4oVgEC8gOf4yh9sd209Pz_Tt0tFZjEMv4eIkP5e9hb0t0UTAflM8A$" rel="noreferrer" target="_blank" moz-do-not-send="true">https://jdk.java.net/20/</a><br>
          <br>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>