From jianglizhou at google.com Thu Feb 2 15:50:17 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Thu, 2 Feb 2023 07:50:17 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal Message-ID: Hi, During the last one and a half years, Google has done some extensive research on linux-x64 with Java static image, as project Hermetic Java [1 ]. We would like to share our experiences/results with the community and present our approach for discussion under the Leyden project. We hope to contribute the work to OpenJDK through project Leyden, via the JEP [2 ] process as needed. With Hermetic Java, our main goal is to create a single executable image including the Java runtime environment, Java application and the dependencies. This addresses some real-world Java deployment issues and challenges that we have encountered over the years. We believe it fits very well with the overall goal of project Leyden in the following aspects: - Provide a build-time created static image derived from an application and JDK; Image executes as a standalone program. - Satisfy closed-world constraints. - Is built on top of OpenJDK and can utilize existing OpenJDK components including the Hotspot VM, runtime JIT compiler (C1, C2), CDS, etc. Our focus has been on the image packaging and formatting part. This works roughly as follows: 1. The executable image (see slide #10 of [1 ]) consists of three sections: the ELF executable section (see slide #14), the JDK runtime section (see slide #20, #21) and the JAR section (see slide #22). The ELF section is at the beginning of the image and contains the Java launcher executable, which allows the image to work as a native executable. The JDK runtime section contains the JDK lib/modules image starting at a page-aligned file offset. This section can include other data that requires special alignment, such as the CDS archive. The JAR section holds the Java application classes, dependent library classes, and resources. JDK runtime resource files, such as java.security and java.policy are also packaged within the JAR section. 1. The Java launcher executable is statically linked with Hotspot/JDK natives and application JNI natives (see slide #15 - #18). For static native library support, we enhance and complete existing OpenJDK work [3 , 4 , 5 ]. It provides a flexible solution for loading built-in (static) native libraries while still allowing dynamically loading shared JNI libraries (if desired). 1. With a single executable image, we define the image file path as the java.home (see slide #23). A JavaHome class is used to provide uniform APIs for accessing JDK resources in traditional and Hermetic Java (single image) execution modes. Hermetic Java is an accumulation of wisdom that Google obtained from real-world production deployments over many years (years before the current project research/experiments). We would love to gather feedback from community members. Any input and feedback are welcome and appreciated! We are happy to provide additional information and answer questions (open to discussions in any form). [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html [3] https://bugs.openjdk.org/browse/JDK-8005716 [4] https://bugs.openjdk.org/browse/JDK-8136556 [5] https://bugs.openjdk.org/browse/JDK-8232748 Best regards, Jiangli -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Thu Feb 2 16:13:34 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Thu, 2 Feb 2023 08:13:34 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: References: Message-ID: (Resending in plain text formatting) Hi, During the last one and a half years, Google has done some extensive research on linux-x64 with Java static image, as project Hermetic Java [1]. We would like to share our experiences/results with the community and present our approach for discussion under the Leyden project. We hope to contribute the work to OpenJDK through project Leyden, via the JEP [2] process as needed. With Hermetic Java, our main goal is to create a single executable image including the Java runtime environment, Java application and the dependencies. This addresses some real-world Java deployment issues and challenges that we have encountered over the years. We believe it fits very well with the overall goal of project Leyden in the following aspects: - Provide a build-time created static image derived from an application and JDK; Image executes as a standalone program. - Satisfy closed-world constraints. - Is built on top of OpenJDK and can utilize existing OpenJDK components including the Hotspot VM, runtime JIT compiler (C1, C2), CDS, etc. Our focus has been on the image packaging and formatting part. This works roughly as follows: 1. The executable image (see slide #10 of [1]) consists of three sections: the ELF executable section (see slide #14), the JDK runtime section (see slide #20, #21) and the JAR section (see slide #22). The ELF section is at the beginning of the image and contains the Java launcher executable, which allows the image to work as a native executable. The JDK runtime section contains the JDK lib/modules image starting at a page-aligned file offset. This section can include other data that requires special alignment, such as the CDS archive. The JAR section holds the Java application classes, dependent library classes, and resources. JDK runtime resource files, such as java.security and java.policy are also packaged within the JAR section. 2. The Java launcher executable is statically linked with Hotspot/JDK natives and application JNI natives (see slide #15 - #18). For static native library support, we enhance and complete existing OpenJDK work [3, 4, 5]. It provides a flexible solution for loading built-in (static) native libraries while still allowing dynamically loading shared JNI libraries (if desired). 3. With a single executable image, we define the image file path as the java.home (see slide #23). A JavaHome class is used to provide uniform APIs for accessing JDK resources in traditional and Hermetic Java (single image) execution modes. Hermetic Java is an accumulation of wisdom that Google obtained from real-world production deployments over many years (years before the current project research/experiments). We would love to gather feedback from community members. Any input and feedback are welcome and appreciated! We are happy to provide additional information and answer questions (open to discussions in any form). [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html [3] https://bugs.openjdk.org/browse/JDK-8005716 [4] https://bugs.openjdk.org/browse/JDK-8136556 [5] https://bugs.openjdk.org/browse/JDK-8232748 Best regards, Jiangli -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Thu Feb 2 17:15:52 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 2 Feb 2023 12:15:52 -0500 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: References: Message-ID: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> Thanks for sharing this information! As far as I understand it, this is a _packaging mechanism_ to take a combination of JDK, application classfiles and resources, and native libraries, and combine them into a single executable, and the benefits of this include "one file to distribute" and "can't run the app on the wrong JDK".? Further, the system classloader has been modified to load classes out of the image rather than from the file system. My question is about your relationship to the "closed world" assumption (and the optimizations that can derive from it); I am unsure of whether you make any closed-world assumptions in your current approach?? Is there any reason why classes cannot be loaded dynamically, `invokedynamic` sites can't be linked dynamically, etc?? Secondarily, does your current implementation perform any optimizations related to faster startup and warmup? My assumption is that the answer is "no restrictions on dynamism, no specific optimizations for startup/warmup, it's purely a packaging mechanism", combined with a reminder that the sorts of optimizations that have been explored elsewhere (Native Image, CraC, SnapStart) could equally well be combined with your packaging approach. Do I have it right? Cheers, -Brian On 2/2/2023 11:13 AM, Jiangli Zhou wrote: > (Resending in plain text formatting) > > Hi, > > During the last one and a half years, Google has done some extensive > research on linux-x64 with Java static image, as project Hermetic Java > [1]. We would like to share our experiences/results with the community > and present our approach for discussion under the Leyden project. We > hope to contribute the work to OpenJDK through project Leyden, via the > JEP [2] process as needed. > > With Hermetic Java, our main goal is to create a single executable > image including the Java runtime environment, Java application and the > dependencies. This addresses some real-world Java deployment issues > and challenges that we have encountered over the years.? We believe it > fits very well with the overall goal of project Leyden in the > following aspects: > > ? - Provide a build-time created static image derived from an > application and JDK; Image executes as a standalone program. > ? - Satisfy closed-world constraints. > ? - Is built on top of OpenJDK and can utilize existing OpenJDK > components including the Hotspot VM, runtime JIT compiler (C1, C2), > CDS, etc. > > Our focus has been on the image packaging and formatting part. This > works roughly as follows: > > 1. The executable image (see slide #10 of [1]) consists of three > sections: the ELF executable section (see slide #14), the JDK runtime > section (see slide #20, #21) and the JAR section (see slide #22). > > The ELF section is at the beginning of the image and contains the Java > launcher executable, which allows the image to work as a native > executable. The JDK runtime section contains the JDK lib/modules image > starting at a page-aligned file offset. This section can include other > data that requires special alignment, such as the CDS archive. The JAR > section holds the Java application classes, dependent library classes, > and resources. JDK runtime resource files, such as java.security and > java.policy are also packaged within the JAR section. > > 2. The Java launcher executable is statically linked with Hotspot/JDK > natives and application JNI natives (see slide #15 - #18). > > For static native library support, we enhance and complete existing > OpenJDK work [3, 4, 5]. It provides a flexible solution for loading > built-in (static) native libraries while still allowing dynamically > loading shared JNI libraries (if desired). > > 3. With a single executable image, we define the image file path as > the java.home (see slide #23). A JavaHome class is used to provide > uniform APIs for accessing JDK resources in traditional and Hermetic > Java (single image) execution modes. > > Hermetic Java is an accumulation of wisdom that Google obtained from > real-world production deployments over many years (years before the > current project research/experiments). We would love to gather > feedback from community members. Any input and feedback are welcome > and appreciated! > > We are happy to provide additional information and answer questions > (open to discussions in any form). > > [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf > > [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html > > [3] https://bugs.openjdk.org/browse/JDK-8005716 > > [4] https://bugs.openjdk.org/browse/JDK-8136556 > > [5] https://bugs.openjdk.org/browse/JDK-8232748 > > Best regards, > > Jiangli -------------- next part -------------- An HTML attachment was scrubbed... URL: From adinn at redhat.com Thu Feb 2 17:31:40 2023 From: adinn at redhat.com (Andrew Dinn) Date: Thu, 2 Feb 2023 17:31:40 +0000 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: References: Message-ID: <8ea6bed0-bd24-7868-1821-0e7788915940@redhat.com> Hi Jiangli, Thanks for pointing the project at this work. Your presentation (rightly) describes Leyden's goals as addressing: Slow startup time Slow time to reach runtime peak performance Large footprint I'm not clear to what degree 'Hermetic Java' helps with any of those. Can you comment and, perhaps, provide some numbers? regards, Andrew Dinn ----------- On 02/02/2023 16:13, Jiangli Zhou wrote: > (Resending in plain text formatting) > > Hi, > > During the last one and a half years, Google has done some extensive > research on linux-x64 with Java static image, as project Hermetic Java > [1]. We would like to share our experiences/results with the community > and present our approach for discussion under the Leyden project. We > hope to contribute the work to OpenJDK through project Leyden, via the > JEP [2] process as needed. > > With Hermetic Java, our main goal is to create a single executable image > including the Java runtime environment, Java application and the > dependencies. This addresses some real-world Java deployment issues and > challenges that we have encountered over the years.? We believe it fits > very well with the overall goal of project Leyden in the following aspects: > > ? - Provide a build-time created static image derived from an > application and JDK; Image executes as a standalone program. > ? - Satisfy closed-world constraints. > ? - Is built on top of OpenJDK and can utilize existing OpenJDK > components including the Hotspot VM, runtime JIT compiler (C1, C2), CDS, > etc. > > Our focus has been on the image packaging and formatting part. This > works roughly as follows: > > 1. The executable image (see slide #10 of [1]) consists of three > sections: the ELF executable section (see slide #14), the JDK runtime > section (see slide #20, #21) and the JAR section (see slide #22). > > The ELF section is at the beginning of the image and contains the Java > launcher executable, which allows the image to work as a native > executable. The JDK runtime section contains the JDK lib/modules image > starting at a page-aligned file offset. This section can include other > data that requires special alignment, such as the CDS archive. The JAR > section holds the Java application classes, dependent library classes, > and resources. JDK runtime resource files, such as java.security and > java.policy are also packaged within the JAR section. > > 2. The Java launcher executable is statically linked with Hotspot/JDK > natives and application JNI natives (see slide #15 - #18). > > For static native library support, we enhance and complete existing > OpenJDK work [3, 4, 5]. It provides a flexible solution for loading > built-in (static) native libraries while still allowing dynamically > loading shared JNI libraries (if desired). > > 3. With a single executable image, we define the image file path as the > java.home (see slide #23). A JavaHome class is used to provide uniform > APIs for accessing JDK resources in traditional and Hermetic Java > (single image) execution modes. > > Hermetic Java is an accumulation of wisdom that Google obtained from > real-world production deployments over many years (years before the > current project research/experiments). We would love to gather feedback > from community members. Any input and feedback are welcome and appreciated! > > We are happy to provide additional information and answer questions > (open to discussions in any form). > > [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf > > > [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html > > > [3] https://bugs.openjdk.org/browse/JDK-8005716 > > > [4] https://bugs.openjdk.org/browse/JDK-8136556 > > > [5] https://bugs.openjdk.org/browse/JDK-8232748 > > > Best regards, > > Jiangli From jianglizhou at google.com Fri Feb 3 01:08:04 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Thu, 2 Feb 2023 17:08:04 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> References: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> Message-ID: Hi Brian, Thanks for the response! On Thu, Feb 2, 2023 at 9:16 AM Brian Goetz wrote: > Thanks for sharing this information! > > As far as I understand it, this is a _packaging mechanism_ to take a > combination of JDK, application classfiles and resources, and native > libraries, and combine them into a single executable, and the benefits of > this include "one file to distribute" and "can't run the app on the wrong > JDK". Further, the system classloader has been modified to load classes > out of the image rather than from the file system. > > My question is about your relationship to the "closed world" assumption > (and the optimizations that can derive from it); I am unsure of whether you > make any closed-world assumptions in your current approach? Is there any > reason why classes cannot be loaded dynamically, `invokedynamic` sites > can't be linked dynamically, etc? Secondarily, does your current > implementation perform any optimizations related to faster startup and > warmup? > > My assumption is that the answer is "no restrictions on dynamism, no > specific optimizations for startup/warmup, it's purely a packaging > mechanism", combined with a reminder that the sorts of optimizations that > have been explored elsewhere (Native Image, CraC, SnapStart) could equally > well be combined with your packaging approach. > > Do I have it right? > You are right in the above. :-) In our current investigation/work, we don't apply any restrictions on loading classes and JNI native libraries. When desired, it can still dynamically load classes and native libraries from outside the image. With a hermetic Java image, our usages (at least all the cases that we have experimented with so far) do not require such flexibility. In those cases, closed world assumptions could be applied. We haven't done any optimization related work yet, beyond the packaging/formatting itself. We hope the hermetic Java image solution can be a vessel to faciality those sorts of optimizations. Best regards, Jiangli > > Cheers, > -Brian > > > > On 2/2/2023 11:13 AM, Jiangli Zhou wrote: > > (Resending in plain text formatting) > > Hi, > > During the last one and a half years, Google has done some extensive > research on linux-x64 with Java static image, as project Hermetic Java [1]. > We would like to share our experiences/results with the community and > present our approach for discussion under the Leyden project. We hope to > contribute the work to OpenJDK through project Leyden, via the JEP [2] > process as needed. > > With Hermetic Java, our main goal is to create a single executable image > including the Java runtime environment, Java application and the > dependencies. This addresses some real-world Java deployment issues and > challenges that we have encountered over the years. We believe it fits > very well with the overall goal of project Leyden in the following aspects: > > - Provide a build-time created static image derived from an application > and JDK; Image executes as a standalone program. > - Satisfy closed-world constraints. > - Is built on top of OpenJDK and can utilize existing OpenJDK components > including the Hotspot VM, runtime JIT compiler (C1, C2), CDS, etc. > > Our focus has been on the image packaging and formatting part. This works > roughly as follows: > > 1. The executable image (see slide #10 of [1]) consists of three sections: > the ELF executable section (see slide #14), the JDK runtime section (see > slide #20, #21) and the JAR section (see slide #22). > > The ELF section is at the beginning of the image and contains the Java > launcher executable, which allows the image to work as a native executable. > The JDK runtime section contains the JDK lib/modules image starting at a > page-aligned file offset. This section can include other data that requires > special alignment, such as the CDS archive. The JAR section holds the Java > application classes, dependent library classes, and resources. JDK runtime > resource files, such as java.security and java.policy are also packaged > within the JAR section. > > 2. The Java launcher executable is statically linked with Hotspot/JDK > natives and application JNI natives (see slide #15 - #18). > > For static native library support, we enhance and complete existing > OpenJDK work [3, 4, 5]. It provides a flexible solution for loading > built-in (static) native libraries while still allowing dynamically loading > shared JNI libraries (if desired). > > 3. With a single executable image, we define the image file path as the > java.home (see slide #23). A JavaHome class is used to provide uniform APIs > for accessing JDK resources in traditional and Hermetic Java (single image) > execution modes. > > Hermetic Java is an accumulation of wisdom that Google obtained from > real-world production deployments over many years (years before the current > project research/experiments). We would love to gather feedback from > community members. Any input and feedback are welcome and appreciated! > > We are happy to provide additional information and answer questions (open > to discussions in any form). > > [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf > > [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html > > [3] https://bugs.openjdk.org/browse/JDK-8005716 > > [4] https://bugs.openjdk.org/browse/JDK-8136556 > > [5] https://bugs.openjdk.org/browse/JDK-8232748 > > Best regards, > > Jiangli > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Fri Feb 3 02:52:19 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Thu, 2 Feb 2023 18:52:19 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <8ea6bed0-bd24-7868-1821-0e7788915940@redhat.com> References: <8ea6bed0-bd24-7868-1821-0e7788915940@redhat.com> Message-ID: Hi Andrew, Thanks for bringing up the question! :-) Currently, the hermetic Java investigation has not done any of the startup/runtime performance or footprint reduction related work. We have only investigated the static image packaging and formatting (also mentioned in the response to Brian's email). Our experiments in real world production environments have found that a single executable image can meet the existing production requirements (for cases that we have tested with) and simplifies configurations/deployments without a separate JDK binary. We would like to share the work with the community early, to find out if we are in the right direction. With hermetic Java image, it has the capability for including pre-digested (e.g. pre-loaded class data and archived heap data in CDS and potentially pre-compiled code) data in a single executable. Hopefully the packaging/formatting investigation may help accelerate some of Leyden's progress. Best regards, Jiangli On Thu, Feb 2, 2023 at 9:31 AM Andrew Dinn wrote: > Hi Jiangli, > > Thanks for pointing the project at this work. > > Your presentation (rightly) describes Leyden's goals as addressing: > > Slow startup time > Slow time to reach runtime peak performance > Large footprint > > I'm not clear to what degree 'Hermetic Java' helps with any of those. > Can you comment and, perhaps, provide some numbers? > > regards, > > > Andrew Dinn > ----------- > > On 02/02/2023 16:13, Jiangli Zhou wrote: > > (Resending in plain text formatting) > > > > Hi, > > > > During the last one and a half years, Google has done some extensive > > research on linux-x64 with Java static image, as project Hermetic Java > > [1]. We would like to share our experiences/results with the community > > and present our approach for discussion under the Leyden project. We > > hope to contribute the work to OpenJDK through project Leyden, via the > > JEP [2] process as needed. > > > > With Hermetic Java, our main goal is to create a single executable image > > including the Java runtime environment, Java application and the > > dependencies. This addresses some real-world Java deployment issues and > > challenges that we have encountered over the years. We believe it fits > > very well with the overall goal of project Leyden in the following > aspects: > > > > - Provide a build-time created static image derived from an > > application and JDK; Image executes as a standalone program. > > - Satisfy closed-world constraints. > > - Is built on top of OpenJDK and can utilize existing OpenJDK > > components including the Hotspot VM, runtime JIT compiler (C1, C2), CDS, > > etc. > > > > Our focus has been on the image packaging and formatting part. This > > works roughly as follows: > > > > 1. The executable image (see slide #10 of [1]) consists of three > > sections: the ELF executable section (see slide #14), the JDK runtime > > section (see slide #20, #21) and the JAR section (see slide #22). > > > > The ELF section is at the beginning of the image and contains the Java > > launcher executable, which allows the image to work as a native > > executable. The JDK runtime section contains the JDK lib/modules image > > starting at a page-aligned file offset. This section can include other > > data that requires special alignment, such as the CDS archive. The JAR > > section holds the Java application classes, dependent library classes, > > and resources. JDK runtime resource files, such as java.security and > > java.policy are also packaged within the JAR section. > > > > 2. The Java launcher executable is statically linked with Hotspot/JDK > > natives and application JNI natives (see slide #15 - #18). > > > > For static native library support, we enhance and complete existing > > OpenJDK work [3, 4, 5]. It provides a flexible solution for loading > > built-in (static) native libraries while still allowing dynamically > > loading shared JNI libraries (if desired). > > > > 3. With a single executable image, we define the image file path as the > > java.home (see slide #23). A JavaHome class is used to provide uniform > > APIs for accessing JDK resources in traditional and Hermetic Java > > (single image) execution modes. > > > > Hermetic Java is an accumulation of wisdom that Google obtained from > > real-world production deployments over many years (years before the > > current project research/experiments). We would love to gather feedback > > from community members. Any input and feedback are welcome and > appreciated! > > > > We are happy to provide additional information and answer questions > > (open to discussions in any form). > > > > [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf > > > > > > [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html > > > > > > [3] https://bugs.openjdk.org/browse/JDK-8005716 > > > > > > [4] https://bugs.openjdk.org/browse/JDK-8136556 > > > > > > [5] https://bugs.openjdk.org/browse/JDK-8232748 > > > > > > Best regards, > > > > Jiangli > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Tue Feb 7 21:36:36 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 7 Feb 2023 16:36:36 -0500 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: References: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> Message-ID: <1bb33f0d-2bb0-946f-6258-ade85c521f5d@oracle.com> I have a few more questions about the scope of the changes here.? As far as I can tell, there are three main areas where you've modified the JDK: ?- the boot classloader, which will look for classes in the ELF before looking on the regular class path; ?- System::loadLibrary and friends, which will similarly look for shared libraries in the ELF before looking on the regular library path; ?- various code paths that look for things in the home directory. Is that a roughly complete list of the modification areas?? If not, what did I miss?? If so, what is the scale and intrusiveness of these modifications?? (For the third item above, for example, I could imagine these changes happening in a lot of places; I'd guess less so for the other two.) Thanks, -Brian On 2/2/2023 8:08 PM, Jiangli Zhou wrote: > Hi?Brian, > > Thanks for the response! > > On Thu, Feb 2, 2023 at 9:16 AM Brian Goetz wrote: > > Thanks for sharing this information! > > As far as I understand it, this is a _packaging mechanism_ to take > a combination of JDK, application classfiles and resources, and > native libraries, and combine them into a single executable, and > the benefits of this include "one file to distribute" and "can't > run the app on the wrong JDK".? Further, the system classloader > has been modified to load classes out of the image rather than > from the file system. > > My question is about your relationship to the "closed world" > assumption (and the optimizations that can derive from it); I am > unsure of whether you make any closed-world assumptions in your > current approach?? Is there any reason why classes cannot be > loaded dynamically, `invokedynamic` sites can't be linked > dynamically, etc?? Secondarily, does your current implementation > perform any optimizations related to faster startup and warmup? > > My assumption is that the answer is "no restrictions on dynamism, > no specific optimizations for startup/warmup, it's purely a > packaging mechanism", combined with a reminder that the sorts of > optimizations that have been explored elsewhere (Native Image, > CraC, SnapStart) could equally well be combined with your > packaging approach. > > Do I have it right? > > > You are right in the above. :-) In our current investigation/work, we > don't apply any restrictions on loading classes and JNI native > libraries. When desired, it can still dynamically load classes and > native libraries from outside the image. With a hermetic Java image, > our usages (at least all the cases that we have experimented with so > far) do not require such flexibility. In those cases, closed world > assumptions could be applied. We haven't done any optimization related > work yet, beyond the packaging/formatting itself. We hope the hermetic > Java image solution can be a vessel to faciality those sorts of > optimizations. > > Best regards, > Jiangli > > > Cheers, > -Brian > > > > On 2/2/2023 11:13 AM, Jiangli Zhou wrote: >> (Resending in plain text formatting) >> >> Hi, >> >> During the last one and a half years, Google has done some >> extensive research on linux-x64 with Java static image, as >> project Hermetic Java [1]. We would like to share our >> experiences/results with the community and present our approach >> for discussion under the Leyden project. We hope to contribute >> the work to OpenJDK through project Leyden, via the JEP [2] >> process as needed. >> >> With Hermetic Java, our main goal is to create a single >> executable image including the Java runtime environment, Java >> application and the dependencies. This addresses some real-world >> Java deployment issues and challenges that we have encountered >> over the years.? We believe it fits very well with the overall >> goal of project Leyden in the following aspects: >> >> ? - Provide a build-time created static image derived from an >> application and JDK; Image executes as a standalone program. >> ? - Satisfy closed-world constraints. >> ? - Is built on top of OpenJDK and can utilize existing OpenJDK >> components including the Hotspot VM, runtime JIT compiler (C1, >> C2), CDS, etc. >> >> Our focus has been on the image packaging and formatting part. >> This works roughly as follows: >> >> 1. The executable image (see slide #10 of [1]) consists of three >> sections: the ELF executable section (see slide #14), the JDK >> runtime section (see slide #20, #21) and the JAR section (see >> slide #22). >> >> The ELF section is at the beginning of the image and contains the >> Java launcher executable, which allows the image to work as a >> native executable. The JDK runtime section contains the JDK >> lib/modules image starting at a page-aligned file offset. This >> section can include other data that requires special alignment, >> such as the CDS archive. The JAR section holds the Java >> application classes, dependent library classes, and resources. >> JDK runtime resource files, such as java.security and java.policy >> are also packaged within the JAR section. >> >> 2. The Java launcher executable is statically linked with >> Hotspot/JDK natives and application JNI natives (see slide #15 - >> #18). >> >> For static native library support, we enhance and complete >> existing OpenJDK work [3, 4, 5]. It provides a flexible solution >> for loading built-in (static) native libraries while still >> allowing dynamically loading shared JNI libraries (if desired). >> >> 3. With a single executable image, we define the image file path >> as the java.home (see slide #23). A JavaHome class is used to >> provide uniform APIs for accessing JDK resources in traditional >> and Hermetic Java (single image) execution modes. >> >> Hermetic Java is an accumulation of wisdom that Google obtained >> from real-world production deployments over many years (years >> before the current project research/experiments). We would love >> to gather feedback from community members. Any input and feedback >> are welcome and appreciated! >> >> We are happy to provide additional information and answer >> questions (open to discussions in any form). >> >> [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf >> >> [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html >> >> [3] https://bugs.openjdk.org/browse/JDK-8005716 >> >> [4] https://bugs.openjdk.org/browse/JDK-8136556 >> >> [5] https://bugs.openjdk.org/browse/JDK-8232748 >> >> Best regards, >> >> Jiangli > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Wed Feb 8 02:08:29 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Tue, 7 Feb 2023 18:08:29 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <1bb33f0d-2bb0-946f-6258-ade85c521f5d@oracle.com> References: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> <1bb33f0d-2bb0-946f-6258-ade85c521f5d@oracle.com> Message-ID: Hi Brian, Here are the main buckets of the changes discovered in JDK/VM to support the proposed hermetic image: 1) Resolve symbol conflicts to fully support JDK static builds. Those are mainly caused by duplicated symbols defined in different native libraries or VM code. 2) Complete the built-in native library support in JDK. For easier and more reliable testing/release/deployment, we wanted to support JDK dynamic and static builds with the same set of object files (.o). We've changed to use unique names for JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach in different JDK JNI libraries by default. For both dynamic linked and static linked JDK builds, we use unique symbols for JNI_OnLoad function and friends. However, non-builtin application JNI libraries can still have the default JNI_OnLoad|... naming. We still properly support application JNI libraries using the default JNI_OnLoad (and friends) naming. As we wanted to produce dynamic and static builds from the same set of object files, we've moved away from using the STATIC_BUILD macro. We've also done some makefile work to build both dynamic shared libraries (DSOs) and static libraries, within one JDK build. 3) Handle dlopen/dlsym in the VM code and native libraries for static builds. 4) The JDK runtime modules image is packed between ELF and JAR section within the hermetic image. We've changed (non-intrusive) the existing jimage loading code to handle the JDK runtime image at a specific file offset (page aligned). 5) Various changes in JDK for accessing JDK resource files from the hermetic image, as you pointed out. Please see more comments inlined. On Tue, Feb 7, 2023 at 1:36 PM Brian Goetz wrote: > > I have a few more questions about the scope of the changes here. As far as I can tell, there are three main areas where you've modified the JDK: > > - the boot classloader, which will look for classes in the ELF before looking on the regular class path; We don't change the class loaders (not yet). The JDK classes are stored in the hermetic image file embedded modules. The NULL class loader works without any modification (for class loading part). > - System::loadLibrary and friends, which will similarly look for shared libraries in the ELF before looking on the regular library path; Yeah, the loadLibrary and friends need to be able look up built-in libraries in the executable (within the image ELF section). The existing JDK code is already able to handle built-in libraries (partially). Please see more details for built-in native support in earlier comments. > - various code paths that look for things in the home directory. Right, that's one of the main parts. > > Is that a roughly complete list of the modification areas? If not, what did I miss? If so, what is the scale and intrusiveness of these modifications? (For the third item above, for example, I could imagine these changes happening in a lot of places; I'd guess less so for the other two.) The changes touch various places/components in both JDK and VM code. Based on our discovery, they appear to be non-intrusive and are mostly localized. The full support for the built-in native libraries is more involved compared to the other changes, but is built on top of the current code and maintains the same spirit. :-) Best, Jiangli > > Thanks, > -Brian > > On 2/2/2023 8:08 PM, Jiangli Zhou wrote: > > Hi Brian, > > Thanks for the response! > > On Thu, Feb 2, 2023 at 9:16 AM Brian Goetz wrote: >> >> Thanks for sharing this information! >> >> As far as I understand it, this is a _packaging mechanism_ to take a combination of JDK, application classfiles and resources, and native libraries, and combine them into a single executable, and the benefits of this include "one file to distribute" and "can't run the app on the wrong JDK". Further, the system classloader has been modified to load classes out of the image rather than from the file system. >> >> My question is about your relationship to the "closed world" assumption (and the optimizations that can derive from it); I am unsure of whether you make any closed-world assumptions in your current approach? Is there any reason why classes cannot be loaded dynamically, `invokedynamic` sites can't be linked dynamically, etc? Secondarily, does your current implementation perform any optimizations related to faster startup and warmup? >> >> My assumption is that the answer is "no restrictions on dynamism, no specific optimizations for startup/warmup, it's purely a packaging mechanism", combined with a reminder that the sorts of optimizations that have been explored elsewhere (Native Image, CraC, SnapStart) could equally well be combined with your packaging approach. >> >> Do I have it right? > > > You are right in the above. :-) In our current investigation/work, we don't apply any restrictions on loading classes and JNI native libraries. When desired, it can still dynamically load classes and native libraries from outside the image. With a hermetic Java image, our usages (at least all the cases that we have experimented with so far) do not require such flexibility. In those cases, closed world assumptions could be applied. We haven't done any optimization related work yet, beyond the packaging/formatting itself. We hope the hermetic Java image solution can be a vessel to faciality those sorts of optimizations. > > Best regards, > Jiangli > >> >> >> Cheers, >> -Brian >> >> >> >> On 2/2/2023 11:13 AM, Jiangli Zhou wrote: >> >> (Resending in plain text formatting) >> >> Hi, >> >> During the last one and a half years, Google has done some extensive research on linux-x64 with Java static image, as project Hermetic Java [1]. We would like to share our experiences/results with the community and present our approach for discussion under the Leyden project. We hope to contribute the work to OpenJDK through project Leyden, via the JEP [2] process as needed. >> >> With Hermetic Java, our main goal is to create a single executable image including the Java runtime environment, Java application and the dependencies. This addresses some real-world Java deployment issues and challenges that we have encountered over the years. We believe it fits very well with the overall goal of project Leyden in the following aspects: >> >> - Provide a build-time created static image derived from an application and JDK; Image executes as a standalone program. >> - Satisfy closed-world constraints. >> - Is built on top of OpenJDK and can utilize existing OpenJDK components including the Hotspot VM, runtime JIT compiler (C1, C2), CDS, etc. >> >> Our focus has been on the image packaging and formatting part. This works roughly as follows: >> >> 1. The executable image (see slide #10 of [1]) consists of three sections: the ELF executable section (see slide #14), the JDK runtime section (see slide #20, #21) and the JAR section (see slide #22). >> >> The ELF section is at the beginning of the image and contains the Java launcher executable, which allows the image to work as a native executable. The JDK runtime section contains the JDK lib/modules image starting at a page-aligned file offset. This section can include other data that requires special alignment, such as the CDS archive. The JAR section holds the Java application classes, dependent library classes, and resources. JDK runtime resource files, such as java.security and java.policy are also packaged within the JAR section. >> >> 2. The Java launcher executable is statically linked with Hotspot/JDK natives and application JNI natives (see slide #15 - #18). >> >> For static native library support, we enhance and complete existing OpenJDK work [3, 4, 5]. It provides a flexible solution for loading built-in (static) native libraries while still allowing dynamically loading shared JNI libraries (if desired). >> >> 3. With a single executable image, we define the image file path as the java.home (see slide #23). A JavaHome class is used to provide uniform APIs for accessing JDK resources in traditional and Hermetic Java (single image) execution modes. >> >> Hermetic Java is an accumulation of wisdom that Google obtained from real-world production deployments over many years (years before the current project research/experiments). We would love to gather feedback from community members. Any input and feedback are welcome and appreciated! >> >> We are happy to provide additional information and answer questions (open to discussions in any form). >> >> [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf >> >> [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html >> >> [3] https://bugs.openjdk.org/browse/JDK-8005716 >> >> [4] https://bugs.openjdk.org/browse/JDK-8136556 >> >> [5] https://bugs.openjdk.org/browse/JDK-8232748 >> >> Best regards, >> >> Jiangli >> >> > From fweimer at redhat.com Mon Feb 13 09:58:43 2023 From: fweimer at redhat.com (Florian Weimer) Date: Mon, 13 Feb 2023 10:58:43 +0100 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: (Jiangli Zhou's message of "Thu, 2 Feb 2023 08:13:34 -0800") References: Message-ID: <87zg9hga3w.fsf@oldenburg.str.redhat.com> * Jiangli Zhou: > 1. The executable image (see slide #10 ofa [1]) consists of three > sections: the ELF executable section (see slide #14), the JDK runtime > section (see slide #20, #21) and the JAR section (see slide #22). These sections are not ELF sections, right? > 2. The Java launcher executable is statically linked with Hotspot/JDK > natives and application JNI natives (see slide #15 - #18). Doesn't this make the resulting executable non-distributable in almost all cases, for licensing reasons? (Hotspot is under the GPL, version 2, most open-source Java libraries use the Apache license, version 2.0, and those two are generally considered incompatible.) At least for those developers who do not have special licensing arrangements with Oracle and thus receive OpenJDK under the default terms (including the assembly exception, but it doesn't seem to help here because it only extends to OpenJDK components). [from further down the thread] > Yeah, the loadLibrary and friends need to be able look up built-in > libraries in the executable (within the image ELF section). The > existing JDK code is already able to handle built-in libraries > (partially). Please see more details for built-in native support in > earlier comments. I believe that will require a custom glibc patch that has not been upstreamed. I think Google's approach is here: The offset argument is then threaded through the entire code, e.g.: There is a different proposed glibc interface for this: [PATCH v2 2/2] dlfcn,elf: implement dlmem() function [BZ #11767] Maybe you could check if that interface could serve your needs as well? Thanks, Florian From Alan.Bateman at oracle.com Mon Feb 13 11:46:09 2023 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 13 Feb 2023 11:46:09 +0000 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <87zg9hga3w.fsf@oldenburg.str.redhat.com> References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> Message-ID: <610a91ed-f0e8-ff70-f081-ece82fc4e7c2@oracle.com> On 13/02/2023 09:58, Florian Weimer wrote: > : >> Yeah, the loadLibrary and friends need to be able look up built-in >> libraries in the executable (within the image ELF section). The >> existing JDK code is already able to handle built-in libraries >> (partially). Please see more details for built-in native support in >> earlier comments. > I believe that will require a custom glibc patch that has not been > upstreamed. JEP 178 [1] added support for statically linking native libs. It might be that this proposal builds on that. -Alan [1] https://openjdk.org/jeps/178 From fweimer at redhat.com Mon Feb 13 12:00:56 2023 From: fweimer at redhat.com (Florian Weimer) Date: Mon, 13 Feb 2023 13:00:56 +0100 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <610a91ed-f0e8-ff70-f081-ece82fc4e7c2@oracle.com> (Alan Bateman's message of "Mon, 13 Feb 2023 11:46:09 +0000") References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> <610a91ed-f0e8-ff70-f081-ece82fc4e7c2@oracle.com> Message-ID: <87cz6depvr.fsf@oldenburg.str.redhat.com> * Alan Bateman: > On 13/02/2023 09:58, Florian Weimer wrote: >> : >>> Yeah, the loadLibrary and friends need to be able look up built-in >>> libraries in the executable (within the image ELF section). The >>> existing JDK code is already able to handle built-in libraries >>> (partially). Please see more details for built-in native support in >>> earlier comments. >> I believe that will require a custom glibc patch that has not been >> upstreamed. > JEP 178 [1] added support for statically linking native libs. It might > be that this proposal builds on that. I was under the impression that it's about loading a separate DSO embedded in the main executable file, without copying out to the file system first. As far as I understand it, there is a mechanism that deals with this for the JAR case, but it requires the extra copy. Thanks, Florian From ron.pressler at oracle.com Mon Feb 13 12:23:48 2023 From: ron.pressler at oracle.com (Ron Pressler) Date: Mon, 13 Feb 2023 12:23:48 +0000 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: References: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> <1bb33f0d-2bb0-946f-6258-ade85c521f5d@oracle.com> Message-ID: This is interesting and very cool! I think, however, that there is one change that could make this somewhat simpler, and more in line with the envisioned direction of the JDK ? and therefore potentially more powerful ? assuming you?re interested in getting the capabilities of Hermetic Java into the JDK. I believe that the JAR section can be made redundant without loss of generality. Instead of a pre-processing stage involving the creation of a fat JAR, the pre-processing step could be jlink. If all the code in the application is modularized, jlink could produce an image containing all classes with no need for a JAR. If, on the other hand, some classes are not modularised, then a separate tool ? perhaps not included in the JDK ? could then produce a *modular* fat JAR out of the remaining non-modular JARs required by the application, with an artificial explicit module that would mimic the behaviour of the unnamed module for the application. This JAR could then be added into the jlinked image. In this way, the capabilities of Hermetic Java could potentially be folded into jlink and evolve together with it. ? Ron > On 8 Feb 2023, at 02:08, Jiangli Zhou wrote: > > Hi Brian, > > Here are the main buckets of the changes discovered in JDK/VM to > support the proposed hermetic image: > > 1) Resolve symbol conflicts to fully support JDK static builds. Those > are mainly caused by duplicated symbols defined in different native > libraries or VM code. > > 2) Complete the built-in native library support in JDK. For easier and > more reliable testing/release/deployment, we wanted to support JDK > dynamic and static builds with the same set of object files (.o). > We've changed to use unique names for > JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach in > different JDK JNI libraries by default. For both dynamic linked and > static linked JDK builds, we use unique symbols for JNI_OnLoad > function and friends. However, non-builtin application JNI libraries > can still have the default JNI_OnLoad|... naming. We still properly > support application JNI libraries using the default JNI_OnLoad (and > friends) naming. > > As we wanted to produce dynamic and static builds from the same set of > object files, we've moved away from using the STATIC_BUILD macro. > > We've also done some makefile work to build both dynamic shared > libraries (DSOs) and static libraries, within one JDK build. > > 3) Handle dlopen/dlsym in the VM code and native libraries for static builds. > > 4) The JDK runtime modules image is packed between ELF and JAR section > within the hermetic image. We've changed (non-intrusive) the existing > jimage loading code to handle the JDK runtime image at a specific file > offset (page aligned). > > 5) Various changes in JDK for accessing JDK resource files from the > hermetic image, as you pointed out. > > Please see more comments inlined. > > On Tue, Feb 7, 2023 at 1:36 PM Brian Goetz wrote: >> >> I have a few more questions about the scope of the changes here. As far as I can tell, there are three main areas where you've modified the JDK: >> >> - the boot classloader, which will look for classes in the ELF before looking on the regular class path; > > We don't change the class loaders (not yet). The JDK classes are > stored in the hermetic image file embedded modules. The NULL class > loader works without any modification (for class loading part). > >> - System::loadLibrary and friends, which will similarly look for shared libraries in the ELF before looking on the regular library path; > > Yeah, the loadLibrary and friends need to be able look up built-in > libraries in the executable (within the image ELF section). The > existing JDK code is already able to handle built-in libraries > (partially). Please see more details for built-in native support in > earlier comments. > >> - various code paths that look for things in the home directory. > > Right, that's one of the main parts. > >> >> Is that a roughly complete list of the modification areas? If not, what did I miss? If so, what is the scale and intrusiveness of these modifications? (For the third item above, for example, I could imagine these changes happening in a lot of places; I'd guess less so for the other two.) > > The changes touch various places/components in both JDK and VM code. > Based on our discovery, they appear to be non-intrusive and are mostly > localized. The full support for the built-in native libraries is more > involved compared to the other changes, but is built on top of the > current code and maintains the same spirit. :-) > > Best, > Jiangli > >> >> Thanks, >> -Brian >> >> On 2/2/2023 8:08 PM, Jiangli Zhou wrote: >> >> Hi Brian, >> >> Thanks for the response! >> >> On Thu, Feb 2, 2023 at 9:16 AM Brian Goetz wrote: >>> >>> Thanks for sharing this information! >>> >>> As far as I understand it, this is a _packaging mechanism_ to take a combination of JDK, application classfiles and resources, and native libraries, and combine them into a single executable, and the benefits of this include "one file to distribute" and "can't run the app on the wrong JDK". Further, the system classloader has been modified to load classes out of the image rather than from the file system. >>> >>> My question is about your relationship to the "closed world" assumption (and the optimizations that can derive from it); I am unsure of whether you make any closed-world assumptions in your current approach? Is there any reason why classes cannot be loaded dynamically, `invokedynamic` sites can't be linked dynamically, etc? Secondarily, does your current implementation perform any optimizations related to faster startup and warmup? >>> >>> My assumption is that the answer is "no restrictions on dynamism, no specific optimizations for startup/warmup, it's purely a packaging mechanism", combined with a reminder that the sorts of optimizations that have been explored elsewhere (Native Image, CraC, SnapStart) could equally well be combined with your packaging approach. >>> >>> Do I have it right? >> >> >> You are right in the above. :-) In our current investigation/work, we don't apply any restrictions on loading classes and JNI native libraries. When desired, it can still dynamically load classes and native libraries from outside the image. With a hermetic Java image, our usages (at least all the cases that we have experimented with so far) do not require such flexibility. In those cases, closed world assumptions could be applied. We haven't done any optimization related work yet, beyond the packaging/formatting itself. We hope the hermetic Java image solution can be a vessel to faciality those sorts of optimizations. >> >> Best regards, >> Jiangli >> >>> >>> >>> Cheers, >>> -Brian >>> >>> >>> >>> On 2/2/2023 11:13 AM, Jiangli Zhou wrote: >>> >>> (Resending in plain text formatting) >>> >>> Hi, >>> >>> During the last one and a half years, Google has done some extensive research on linux-x64 with Java static image, as project Hermetic Java [1]. We would like to share our experiences/results with the community and present our approach for discussion under the Leyden project. We hope to contribute the work to OpenJDK through project Leyden, via the JEP [2] process as needed. >>> >>> With Hermetic Java, our main goal is to create a single executable image including the Java runtime environment, Java application and the dependencies. This addresses some real-world Java deployment issues and challenges that we have encountered over the years. We believe it fits very well with the overall goal of project Leyden in the following aspects: >>> >>> - Provide a build-time created static image derived from an application and JDK; Image executes as a standalone program. >>> - Satisfy closed-world constraints. >>> - Is built on top of OpenJDK and can utilize existing OpenJDK components including the Hotspot VM, runtime JIT compiler (C1, C2), CDS, etc. >>> >>> Our focus has been on the image packaging and formatting part. This works roughly as follows: >>> >>> 1. The executable image (see slide #10 of [1]) consists of three sections: the ELF executable section (see slide #14), the JDK runtime section (see slide #20, #21) and the JAR section (see slide #22). >>> >>> The ELF section is at the beginning of the image and contains the Java launcher executable, which allows the image to work as a native executable. The JDK runtime section contains the JDK lib/modules image starting at a page-aligned file offset. This section can include other data that requires special alignment, such as the CDS archive. The JAR section holds the Java application classes, dependent library classes, and resources. JDK runtime resource files, such as java.security and java.policy are also packaged within the JAR section. >>> >>> 2. The Java launcher executable is statically linked with Hotspot/JDK natives and application JNI natives (see slide #15 - #18). >>> >>> For static native library support, we enhance and complete existing OpenJDK work [3, 4, 5]. It provides a flexible solution for loading built-in (static) native libraries while still allowing dynamically loading shared JNI libraries (if desired). >>> >>> 3. With a single executable image, we define the image file path as the java.home (see slide #23). A JavaHome class is used to provide uniform APIs for accessing JDK resources in traditional and Hermetic Java (single image) execution modes. >>> >>> Hermetic Java is an accumulation of wisdom that Google obtained from real-world production deployments over many years (years before the current project research/experiments). We would love to gather feedback from community members. Any input and feedback are welcome and appreciated! >>> >>> We are happy to provide additional information and answer questions (open to discussions in any form). >>> >>> [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf >>> >>> [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html >>> >>> [3] https://bugs.openjdk.org/browse/JDK-8005716 >>> >>> [4] https://bugs.openjdk.org/browse/JDK-8136556 >>> >>> [5] https://bugs.openjdk.org/browse/JDK-8232748 >>> >>> Best regards, >>> >>> Jiangli >>> >>> >> From ron.pressler at oracle.com Mon Feb 13 12:25:55 2023 From: ron.pressler at oracle.com (Ron Pressler) Date: Mon, 13 Feb 2023 12:25:55 +0000 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <87zg9hga3w.fsf@oldenburg.str.redhat.com> References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> Message-ID: > On 13 Feb 2023, at 09:58, Florian Weimer wrote: > > Doesn't this make the resulting executable non-distributable in almost > all cases, for licensing reasons? (Hotspot is under the GPL, version 2, > most open-source Java libraries use the Apache license, version 2.0, and > those two are generally considered incompatible.) I?m not sure your interpretation of the GPL+CPE is correct, but I don?t know if anyone here can give a definitive answer. ? Ron From magnus.ihse.bursie at oracle.com Mon Feb 13 13:42:51 2023 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Mon, 13 Feb 2023 14:42:51 +0100 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: References: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> <1bb33f0d-2bb0-946f-6258-ade85c521f5d@oracle.com> Message-ID: Hi Jiangli, On 2023-02-08 03:08, Jiangli Zhou wrote: > Hi Brian, > > Here are the main buckets of the changes discovered in JDK/VM to > support the proposed hermetic image: > > 1) Resolve symbol conflicts to fully support JDK static builds. Those > are mainly caused by duplicated symbols defined in different native > libraries or VM code. > > 2) Complete the built-in native library support in JDK. For easier and > more reliable testing/release/deployment, we wanted to support JDK > dynamic and static builds with the same set of object files (.o). > We've changed to use unique names for > JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach in > different JDK JNI libraries by default. For both dynamic linked and > static linked JDK builds, we use unique symbols for JNI_OnLoad > function and friends. However, non-builtin application JNI libraries > can still have the default JNI_OnLoad|... naming. We still properly > support application JNI libraries using the default JNI_OnLoad (and > friends) naming. > > As we wanted to produce dynamic and static builds from the same set of > object files, we've moved away from using the STATIC_BUILD macro. > > We've also done some makefile work to build both dynamic shared > libraries (DSOs) and static libraries, within one JDK build. This sounds like interesting work indeed. However, I am inclined to agree with Andrew and wonder how much it relates to Project Leyden. It might be that Leyden will need some kind of packaging story, and that this can have a role to play in that. But it is not immediately clear that it does fit in, and indeed, I think this is not one of Leyden main problem areas at the time. But your code sounds very much interesting from a pure build perspective! For at least this part of the code, I think you should ignore Leyden for now, and just see if the static build changes you have made could be fit for inclusion in OpenJDK. The static build part of the build system has been sadly neglected due to resource limitations, for a long time. :( The rudimentary system (actually, more like two separate systems) we have was put in place mostly due to external requirements from Project Mobile and the Graal integration, and was tacked on mostly as an after-thought. It is not regularly tested, and I'd frankly be surprised if it actually works right now. So I fully understand if you have been staying away from STATIC_BUILD. :) It sounds like you have created a more dynamic system to be able to select per library, if it should be compiled statically or dynamically. Do I understand you correctly? If done correctly, it can probably help bring a better abstraction to the build process. If you are willing to contribute your work to OpenJDK, I would definitely be interested in studying it in detail. As you might be aware, contributions to OpenJDK must be done on the OpenJDK infrastructure. One way to do this is to create a branch in the sandbox repo[1], and push your changes there. If it turns out to be of use for Project Leyden, all the better if it is already in place. And if it turns out that this is orthogonal to Project Leyden, I still think a cleanup in this area might be beneficial for all of the JDK. /Magnus [1] https://github.com/openjdk/jdk-sandbox From fweimer at redhat.com Mon Feb 13 14:40:56 2023 From: fweimer at redhat.com (Florian Weimer) Date: Mon, 13 Feb 2023 15:40:56 +0100 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: (Ron Pressler's message of "Mon, 13 Feb 2023 12:25:55 +0000") References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> Message-ID: <87r0utd3wn.fsf@oldenburg.str.redhat.com> * Ron Pressler: >> On 13 Feb 2023, at 09:58, Florian Weimer wrote: >> >> Doesn't this make the resulting executable non-distributable in almost >> all cases, for licensing reasons? (Hotspot is under the GPL, version 2, >> most open-source Java libraries use the Apache license, version 2.0, and >> those two are generally considered incompatible.) > > I?m not sure your interpretation of the GPL+CPE is correct, but I > don?t know if anyone here can give a definitive answer. Just to clarify, I don't see any indication why the resulting amalgamation would be covered by the Classpath exception. After all, it includes Hotspot, which itself is not covered. This should make it easier to understand the default requirements (in the absence of private agreements with the copyright holder). But you are right that we likely won't get a definitive answer on this list. Project Leyden should not be affected by this because its key aspects are unrelated to distribution matters. Thanks, Florian From jianglizhou at google.com Mon Feb 13 18:44:49 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Mon, 13 Feb 2023 10:44:49 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <87zg9hga3w.fsf@oldenburg.str.redhat.com> References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> Message-ID: Hi Florian, Thanks for looking into this! On Mon, Feb 13, 2023 at 1:58 AM Florian Weimer wrote: > * Jiangli Zhou: > > > 1. The executable image (see slide #10 ofa [1]) consists of three > > sections: the ELF executable section (see slide #14), the JDK runtime > > section (see slide #20, #21) and the JAR section (see slide #22). > > These sections are not ELF sections, right? > Just to clarify that the ELF sections you referred to in the above are the sections within an ELF file (e.g. https://manpages.debian.org/stretch/manpages/elf.5.en.html), if my understanding is correct. The sections described for a hermetic Java image are indeed not ELF sections in that sense. An ELF file as a whole is encapsulated in the hermetic image at the beginning. We can use a better name (if ELF section may cause any confusions), e.g. executable section, to describe the section containing the ELF file. > > > 2. The Java launcher executable is statically linked with Hotspot/JDK > > natives and application JNI natives (see slide #15 - #18). > > Doesn't this make the resulting executable non-distributable in almost > all cases, for licensing reasons? (Hotspot is under the GPL, version 2, > most open-source Java libraries use the Apache license, version 2.0, and > those two are generally considered incompatible.) At least for those > developers who do not have special licensing arrangements with Oracle > and thus receive OpenJDK under the default terms (including the assembly > exception, but it doesn't seem to help here because it only extends to > OpenJDK components). > Those are good questions. I have to admit that I'm not the appropriate one equipped with the right set of knowledge to answer these questions. This mailing list may not be the proper forum for the topic either. It's probably a good idea to seek the right set of experts and channels for discussions and possible solutions. > > [from further down the thread] > > > Yeah, the loadLibrary and friends need to be able look up built-in > > libraries in the executable (within the image ELF section). The > > existing JDK code is already able to handle built-in libraries > > (partially). Please see more details for built-in native support in > > earlier comments. > > I believe that will require a custom glibc patch that has not been > upstreamed. I think Google's approach is here: > > < > https://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlopen.c;h=faf7a48ea71df186b3581235bffcc7a3692f1325;hb=refs/heads/google/grte/v5-2.27/master#l95 > > > The loadLibrary work for built-in native libraries (with JDK static support) does not require the glibc patch for dlopen_with_offset. During the investigation, we evaluated different approaches and I prototyped the alternative approach (slide #18 in http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf) using dlopen_with_offset, before looking into the JDK static support. dlopen_with_offset would be needed if the DSOs (not statically linked with the executable) were embedded within an image. We decided not to go with that due to several considerations. The main ones include: - dlopen_with_offset has not landed in glibc, and there is no plan to do so AFAIK - When a shared library is embedded in an executable image (as illustrated in slide #18 in http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf), there are issues for the existing standard tools (e.g. perf) to identify the build ID for mapping the correct symbol file associated with the DSO. This's the bigger reason why we did not choose file embedded DSOs. Happy to provide additional details from the investigation on this, if you are interested. > The offset argument is then threaded through the entire code, e.g.: > > < > https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/dl-open.c;h=178270ca1554c1a81db794fb110a962693839887;hb=refs/heads/google/grte/v5-2.27/master#l539 > > > > There is a different proposed glibc interface for this: > > [PATCH v2 2/2] dlfcn,elf: implement dlmem() function [BZ #11767] > > > Maybe you could check if that interface could serve your needs as well? > Thanks for pointing to dlmem(). So it looks like we could read the DSO into a buffer then load with dlmem(). Cool! The build ID and symbol file mapping could still be problematic? Best, Jiangli > > Thanks, > Florian > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Mon Feb 13 19:59:49 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Mon, 13 Feb 2023 11:59:49 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <610a91ed-f0e8-ff70-f081-ece82fc4e7c2@oracle.com> References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> <610a91ed-f0e8-ff70-f081-ece82fc4e7c2@oracle.com> Message-ID: On Mon, Feb 13, 2023 at 3:46 AM Alan Bateman wrote: > On 13/02/2023 09:58, Florian Weimer wrote: > > : > >> Yeah, the loadLibrary and friends need to be able look up built-in > >> libraries in the executable (within the image ELF section). The > >> existing JDK code is already able to handle built-in libraries > >> (partially). Please see more details for built-in native support in > >> earlier comments. > > I believe that will require a custom glibc patch that has not been > > upstreamed. > JEP 178 [1] added support for statically linking native libs. It might > be that this proposal builds on that. > Right, the current proposal was built on top of JEP 178 by making it as a complete solution. Best, Jiangli > -Alan > > [1] https://openjdk.org/jeps/178 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Mon Feb 13 20:50:01 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Mon, 13 Feb 2023 12:50:01 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <87cz6depvr.fsf@oldenburg.str.redhat.com> References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> <610a91ed-f0e8-ff70-f081-ece82fc4e7c2@oracle.com> <87cz6depvr.fsf@oldenburg.str.redhat.com> Message-ID: On Mon, Feb 13, 2023 at 4:01 AM Florian Weimer wrote: > * Alan Bateman: > > > On 13/02/2023 09:58, Florian Weimer wrote: > >> : > >>> Yeah, the loadLibrary and friends need to be able look up built-in > >>> libraries in the executable (within the image ELF section). The > >>> existing JDK code is already able to handle built-in libraries > >>> (partially). Please see more details for built-in native support in > >>> earlier comments. > >> I believe that will require a custom glibc patch that has not been > >> upstreamed. > > > JEP 178 [1] added support for statically linking native libs. It might > > be that this proposal builds on that. > > I was under the impression that it's about loading a separate DSO > embedded in the main executable file, without copying out to the file > system first. As far as I understand it, there is a mechanism that > deals with this for the JAR case, but it requires the extra copy. > Florian, The current proposal is built on top of the existing OpenJDK static support. We did prototyping for the file embedded DSO approach (it worked experimentally for Java in my test) and had multiple rounds of internal discussions with the folks involved in C++ tool chain, profiling tools (and kernel). We've determined that was not a desirable solution. Please see the previous email for more details on the issues with file embedded DSOs approach. We also considered startup-time/install-time extraction. Based on the feedback from other language usages in real production, extraction has real production challenges in many cases, including (tmpfs) file system configuration/management issues, possible security vulnerabilities, temp space pollution, extraction conflicts, and etc. (thanks to the feedback from other language experts from their experiences!). Those make the extraction approach unattractive. Best, Jiangli > Thanks, > Florian > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Mon Feb 13 21:14:31 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Mon, 13 Feb 2023 13:14:31 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: References: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> <1bb33f0d-2bb0-946f-6258-ade85c521f5d@oracle.com> Message-ID: Hi Ron, On Mon, Feb 13, 2023 at 4:23 AM Ron Pressler wrote: > This is interesting and very cool! > > I think, however, that there is one change that could make this somewhat > simpler, and more in line with the envisioned direction of the JDK ? and > therefore potentially more powerful ? assuming you?re interested in getting > the capabilities of Hermetic Java into the JDK. > Indeed, we are interested in getting the capabilities into OpenJDK. > I believe that the JAR section can be made redundant without loss of > generality. Instead of a pre-processing stage involving the creation of a > fat JAR, the pre-processing step could be jlink. If all the code in the > application is modularized, jlink could produce an image containing all > classes with no need for a JAR. > > If, on the other hand, some classes are not modularised, then a separate > tool ? perhaps not included in the JDK ? could then produce a *modular* fat > JAR out of the remaining non-modular JARs required by the application, with > an artificial explicit module that would mimic the behaviour of the unnamed > module for the application. This JAR could then be added into the jlinked > image. > > In this way, the capabilities of Hermetic Java could potentially be folded > into jlink and evolve together with it. > We haven't experimented with jlink for hermetic image yet. I can imagine that would help optimize image size and it's certainly interesting/beneficial to look into that. Reducing image size helps both testing and production usages. Best, Jiangli > > ? Ron > > > On 8 Feb 2023, at 02:08, Jiangli Zhou wrote: > > > > Hi Brian, > > > > Here are the main buckets of the changes discovered in JDK/VM to > > support the proposed hermetic image: > > > > 1) Resolve symbol conflicts to fully support JDK static builds. Those > > are mainly caused by duplicated symbols defined in different native > > libraries or VM code. > > > > 2) Complete the built-in native library support in JDK. For easier and > > more reliable testing/release/deployment, we wanted to support JDK > > dynamic and static builds with the same set of object files (.o). > > We've changed to use unique names for > > JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach in > > different JDK JNI libraries by default. For both dynamic linked and > > static linked JDK builds, we use unique symbols for JNI_OnLoad > > function and friends. However, non-builtin application JNI libraries > > can still have the default JNI_OnLoad|... naming. We still properly > > support application JNI libraries using the default JNI_OnLoad (and > > friends) naming. > > > > As we wanted to produce dynamic and static builds from the same set of > > object files, we've moved away from using the STATIC_BUILD macro. > > > > We've also done some makefile work to build both dynamic shared > > libraries (DSOs) and static libraries, within one JDK build. > > > > 3) Handle dlopen/dlsym in the VM code and native libraries for static > builds. > > > > 4) The JDK runtime modules image is packed between ELF and JAR section > > within the hermetic image. We've changed (non-intrusive) the existing > > jimage loading code to handle the JDK runtime image at a specific file > > offset (page aligned). > > > > 5) Various changes in JDK for accessing JDK resource files from the > > hermetic image, as you pointed out. > > > > Please see more comments inlined. > > > > On Tue, Feb 7, 2023 at 1:36 PM Brian Goetz > wrote: > >> > >> I have a few more questions about the scope of the changes here. As > far as I can tell, there are three main areas where you've modified the JDK: > >> > >> - the boot classloader, which will look for classes in the ELF before > looking on the regular class path; > > > > We don't change the class loaders (not yet). The JDK classes are > > stored in the hermetic image file embedded modules. The NULL class > > loader works without any modification (for class loading part). > > > >> - System::loadLibrary and friends, which will similarly look for shared > libraries in the ELF before looking on the regular library path; > > > > Yeah, the loadLibrary and friends need to be able look up built-in > > libraries in the executable (within the image ELF section). The > > existing JDK code is already able to handle built-in libraries > > (partially). Please see more details for built-in native support in > > earlier comments. > > > >> - various code paths that look for things in the home directory. > > > > Right, that's one of the main parts. > > > >> > >> Is that a roughly complete list of the modification areas? If not, > what did I miss? If so, what is the scale and intrusiveness of these > modifications? (For the third item above, for example, I could imagine > these changes happening in a lot of places; I'd guess less so for the other > two.) > > > > The changes touch various places/components in both JDK and VM code. > > Based on our discovery, they appear to be non-intrusive and are mostly > > localized. The full support for the built-in native libraries is more > > involved compared to the other changes, but is built on top of the > > current code and maintains the same spirit. :-) > > > > Best, > > Jiangli > > > >> > >> Thanks, > >> -Brian > >> > >> On 2/2/2023 8:08 PM, Jiangli Zhou wrote: > >> > >> Hi Brian, > >> > >> Thanks for the response! > >> > >> On Thu, Feb 2, 2023 at 9:16 AM Brian Goetz > wrote: > >>> > >>> Thanks for sharing this information! > >>> > >>> As far as I understand it, this is a _packaging mechanism_ to take a > combination of JDK, application classfiles and resources, and native > libraries, and combine them into a single executable, and the benefits of > this include "one file to distribute" and "can't run the app on the wrong > JDK". Further, the system classloader has been modified to load classes > out of the image rather than from the file system. > >>> > >>> My question is about your relationship to the "closed world" > assumption (and the optimizations that can derive from it); I am unsure of > whether you make any closed-world assumptions in your current approach? Is > there any reason why classes cannot be loaded dynamically, `invokedynamic` > sites can't be linked dynamically, etc? Secondarily, does your current > implementation perform any optimizations related to faster startup and > warmup? > >>> > >>> My assumption is that the answer is "no restrictions on dynamism, no > specific optimizations for startup/warmup, it's purely a packaging > mechanism", combined with a reminder that the sorts of optimizations that > have been explored elsewhere (Native Image, CraC, SnapStart) could equally > well be combined with your packaging approach. > >>> > >>> Do I have it right? > >> > >> > >> You are right in the above. :-) In our current investigation/work, we > don't apply any restrictions on loading classes and JNI native libraries. > When desired, it can still dynamically load classes and native libraries > from outside the image. With a hermetic Java image, our usages (at least > all the cases that we have experimented with so far) do not require such > flexibility. In those cases, closed world assumptions could be applied. We > haven't done any optimization related work yet, beyond the > packaging/formatting itself. We hope the hermetic Java image solution can > be a vessel to faciality those sorts of optimizations. > >> > >> Best regards, > >> Jiangli > >> > >>> > >>> > >>> Cheers, > >>> -Brian > >>> > >>> > >>> > >>> On 2/2/2023 11:13 AM, Jiangli Zhou wrote: > >>> > >>> (Resending in plain text formatting) > >>> > >>> Hi, > >>> > >>> During the last one and a half years, Google has done some extensive > research on linux-x64 with Java static image, as project Hermetic Java [1]. > We would like to share our experiences/results with the community and > present our approach for discussion under the Leyden project. We hope to > contribute the work to OpenJDK through project Leyden, via the JEP [2] > process as needed. > >>> > >>> With Hermetic Java, our main goal is to create a single executable > image including the Java runtime environment, Java application and the > dependencies. This addresses some real-world Java deployment issues and > challenges that we have encountered over the years. We believe it fits > very well with the overall goal of project Leyden in the following aspects: > >>> > >>> - Provide a build-time created static image derived from an > application and JDK; Image executes as a standalone program. > >>> - Satisfy closed-world constraints. > >>> - Is built on top of OpenJDK and can utilize existing OpenJDK > components including the Hotspot VM, runtime JIT compiler (C1, C2), CDS, > etc. > >>> > >>> Our focus has been on the image packaging and formatting part. This > works roughly as follows: > >>> > >>> 1. The executable image (see slide #10 of [1]) consists of three > sections: the ELF executable section (see slide #14), the JDK runtime > section (see slide #20, #21) and the JAR section (see slide #22). > >>> > >>> The ELF section is at the beginning of the image and contains the Java > launcher executable, which allows the image to work as a native executable. > The JDK runtime section contains the JDK lib/modules image starting at a > page-aligned file offset. This section can include other data that requires > special alignment, such as the CDS archive. The JAR section holds the Java > application classes, dependent library classes, and resources. JDK runtime > resource files, such as java.security and java.policy are also packaged > within the JAR section. > >>> > >>> 2. The Java launcher executable is statically linked with Hotspot/JDK > natives and application JNI natives (see slide #15 - #18). > >>> > >>> For static native library support, we enhance and complete existing > OpenJDK work [3, 4, 5]. It provides a flexible solution for loading > built-in (static) native libraries while still allowing dynamically loading > shared JNI libraries (if desired). > >>> > >>> 3. With a single executable image, we define the image file path as > the java.home (see slide #23). A JavaHome class is used to provide uniform > APIs for accessing JDK resources in traditional and Hermetic Java (single > image) execution modes. > >>> > >>> Hermetic Java is an accumulation of wisdom that Google obtained from > real-world production deployments over many years (years before the current > project research/experiments). We would love to gather feedback from > community members. Any input and feedback are welcome and appreciated! > >>> > >>> We are happy to provide additional information and answer questions > (open to discussions in any form). > >>> > >>> [1] http://cr.openjdk.java.net/~jiangli/hermetic_java.pdf > >>> > >>> [2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html > >>> > >>> [3] https://bugs.openjdk.org/browse/JDK-8005716 > >>> > >>> [4] https://bugs.openjdk.org/browse/JDK-8136556 > >>> > >>> [5] https://bugs.openjdk.org/browse/JDK-8232748 > >>> > >>> Best regards, > >>> > >>> Jiangli > >>> > >>> > >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Mon Feb 13 23:52:14 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Mon, 13 Feb 2023 15:52:14 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: References: <3ff54387-7a5f-8825-8c7f-f7ed92b691af@oracle.com> <1bb33f0d-2bb0-946f-6258-ade85c521f5d@oracle.com> Message-ID: Hi Magnus, Thanks for the thoughts! Please see comments inlined below. On Mon, Feb 13, 2023 at 5:43 AM Magnus Ihse Bursie < magnus.ihse.bursie at oracle.com> wrote: > Hi Jiangli, > > On 2023-02-08 03:08, Jiangli Zhou wrote: > > Hi Brian, > > > > Here are the main buckets of the changes discovered in JDK/VM to > > support the proposed hermetic image: > > > > 1) Resolve symbol conflicts to fully support JDK static builds. Those > > are mainly caused by duplicated symbols defined in different native > > libraries or VM code. > > > > 2) Complete the built-in native library support in JDK. For easier and > > more reliable testing/release/deployment, we wanted to support JDK > > dynamic and static builds with the same set of object files (.o). > > We've changed to use unique names for > > JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach in > > different JDK JNI libraries by default. For both dynamic linked and > > static linked JDK builds, we use unique symbols for JNI_OnLoad > > function and friends. However, non-builtin application JNI libraries > > can still have the default JNI_OnLoad|... naming. We still properly > > support application JNI libraries using the default JNI_OnLoad (and > > friends) naming. > > > > As we wanted to produce dynamic and static builds from the same set of > > object files, we've moved away from using the STATIC_BUILD macro. > > > > We've also done some makefile work to build both dynamic shared > > libraries (DSOs) and static libraries, within one JDK build. > > This sounds like interesting work indeed. However, I am inclined to > agree with Andrew and wonder how much it relates to Project Leyden. It > might be that Leyden will need some kind of packaging story, and that > this can have a role to play in that. But it is not immediately clear > that it does fit in, and indeed, I think this is not one of Leyden main > problem areas at the time. > > But your code sounds very much interesting from a pure build > perspective! For at least this part of the code, I think you should > ignore Leyden for now, and just see if the static build changes you have > made could be fit for inclusion in OpenJDK. > > The static build part of the build system has been sadly neglected due > to resource limitations, for a long time. :( The rudimentary system > (actually, more like two separate systems) we have was put in place > mostly due to external requirements from Project Mobile and the Graal > integration, and was tacked on mostly as an after-thought. It is not > regularly tested, and I'd frankly be surprised if it actually works > right now. So I fully understand if you have been staying away from > STATIC_BUILD. :) > > It sounds like you have created a more dynamic system to be able to > select per library, if it should be compiled statically or dynamically. > Do I understand you correctly? If done correctly, it can probably help > bring a better abstraction to the build process. > For JDK/hotspot natives, our experiment/prototype builds all the JDK regular artifacts (e.g. lib/.../*.so) that the existing JDK build produces. Additionally, it also creates the JDK static libraries (e.g. lib_static/*.a) and a bin/javastatic (with most of the needed JDK static libraries statically linked into the launcher, for testing purposes only, such as running jtreg tests) in the binary, as part of the single JDK build. The hermetic image creation is done as a post process, which takes the needed pre-built JDK static libraries for linking into the final executable. The post process is done outside the JDK build. The JDK runtime support is enhanced to be able to support both built-in libraries and dynamically loaded shared libraries. It doesn't seem to be problematic to get the JDK static support into OpenJDK first. It's especially helpful for you or erikj@ to look at the makefiles changes and help massage the changes according to the JDK build standard. > > If you are willing to contribute your work to OpenJDK, I would > definitely be interested in studying it in detail. Thanks! > As you might be > aware, contributions to OpenJDK must be done on the OpenJDK > infrastructure. One way to do this is to create a branch in the sandbox > repo[1], and push your changes there. > Will get back to you on this, after some explorations on open sourcing the changes. > > If it turns out to be of use for Project Leyden, all the better if it is > already in place. And if it turns out that this is orthogonal to Project > Leyden, I still think a cleanup in this area might be beneficial for all > of the JDK. > All sounds good! Best, Jiangli > > /Magnus > > [1] https://github.com/openjdk/jdk-sandbox > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fweimer at redhat.com Tue Feb 14 09:03:12 2023 From: fweimer at redhat.com (Florian Weimer) Date: Tue, 14 Feb 2023 10:03:12 +0100 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: (Jiangli Zhou's message of "Mon, 13 Feb 2023 10:44:49 -0800") References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> Message-ID: <871qmsbovj.fsf@oldenburg.str.redhat.com> * Jiangli Zhou: > On Mon, Feb 13, 2023 at 1:58 AM Florian Weimer wrote: > > * Jiangli Zhou: > > > 1. The executable image (see slide #10 ofa [1]) consists of three > > sections: the ELF executable section (see slide #14), the JDK runtime > > section (see slide #20, #21) and the JAR section (see slide #22). > > These sections are not ELF sections, right? > > Just to clarify that the ELF sections you referred to in the above are > the sections within an ELF file > (e.g. https://manpages.debian.org/stretch/manpages/elf.5.en.html), if > my understanding is correct. The sections described for a hermetic > Java image are indeed not ELF sections in that sense. An ELF file as a > whole is encapsulated in the hermetic image at the beginning. We can > use a better name (if ELF section may cause any confusions), > e.g. executable section, to describe the section containing the ELF > file. I wouldn't use ?section? or ?segment? in this context if it's not about the ELF constructs. ELF doesn't use ?part? or ?appendix? as terminology, so that would work. > [from further down the thread] > > > Yeah, the loadLibrary and friends need to be able look up built-in > > libraries in the executable (within the image ELF section). The > > existing JDK code is already able to handle built-in libraries > > (partially). Please see more details for built-in native support in > > earlier comments. > > I believe that will require a custom glibc patch that has not been > upstreamed. I think Google's approach is here: > > > > > > The loadLibrary work for built-in native libraries (with JDK static > support) does not require the glibc patch for dlopen_with_offset. Okay, but that means that Hotspot can't be re-linked or unbundled. > There is a different proposed glibc interface for this: > > [PATCH v2 2/2] dlfcn,elf: implement dlmem() function [BZ #11767] > > > Maybe you could check if that interface could serve your needs as well? > > Thanks for pointing to dlmem(). So it looks like we could read the DSO > into a buffer then load with dlmem(). Cool! The build ID and symbol > file mapping could still be problematic? I don't think so, it's linked into the glibc dynamic loader data structures like any other mapping. It probably depends on the tooling. If it uses DT_DEBUG/_r_debug, it should be able to identify these mappings even though they are not file-based. If the tooling uses /proc/PID/maps and not _r_debug, that's of course a different matter. Note that dlmem is just a proposed new interface for now. Thanks, Florian From fweimer at redhat.com Tue Feb 14 09:37:14 2023 From: fweimer at redhat.com (Florian Weimer) Date: Tue, 14 Feb 2023 10:37:14 +0100 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: (Jiangli Zhou's message of "Mon, 13 Feb 2023 12:50:01 -0800") References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> <610a91ed-f0e8-ff70-f081-ece82fc4e7c2@oracle.com> <87cz6depvr.fsf@oldenburg.str.redhat.com> Message-ID: <87wn4ka8qd.fsf@oldenburg.str.redhat.com> * Jiangli Zhou: > We also considered startup-time/install-time extraction. Based on the > feedback from other language usages in real production, extraction has > real production challenges in many cases, including (tmpfs) file > system configuration/management issues, possible security > vulnerabilities, temp space pollution, extraction conflicts, and > etc. (thanks to the feedback from other language experts from their > experiences!). Those make the extraction approach unattractive. I thought that OpenJDK has its own DSO-from-JAR extractor? There's memfd_create, which is currently an un-auditable trapdoor to the world of self-modifying code (although I expect that will be closed off eventually). It works even if /tmp, /dev/shm, etc. are all mounted noexec. Experimenting with it suggests that GDB doesn't rely on link map data exclusively. It gets somewhat confused and doesn't read the symbols: (gdb) info shared >From To Syms Read Shared Object Library 0x00007f00a83a1700 0x00007f00a84f519d Yes /lib64/libc.so.6 0x00007f00a85720a0 0x00007f00a85980e5 Yes /lib64/ld-linux-x86-64.so.2 No /proc/589166/fd/3 This should work, but it does not. 8-( Even the non-debugging ELF symbols are missing. The dlmem implementation posted to libc-alpha probably has even more problems. I'm no longer convinced that the public link map (reachable via _r_debug) has sufficient information for debuggers. But if we could fix these issues, the memfd_create approach could be a viable replacement for extracting DSOs from JAR files (to turn this slightly more on-topic). Thanks, Florian From sgehwolf at redhat.com Tue Feb 14 13:39:46 2023 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Tue, 14 Feb 2023 14:39:46 +0100 Subject: File Format Investigation: jimage Message-ID: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> Hi, We have been looking at lib/modules (a.k.a jimage) as a potential candidate format for Project Leyden. Along the way, I've documented how the file is structured[1] and used in its current form. The document discussing jimage in the context of Leyden is here: https://cr.openjdk.org/~sgehwolf/leyden/jimage_file_format_investigation_leyden.pdf Looking forward to your feedback! Thanks, Severin [1] https://cr.openjdk.org/~sgehwolf/leyden/jimage_visualization_1.png From brian.goetz at oracle.com Tue Feb 14 21:50:08 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 14 Feb 2023 16:50:08 -0500 Subject: File Format Investigation: jimage In-Reply-To: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> References: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> Message-ID: <471744e2-d638-c441-0e39-e4127c972371@oracle.com> Nice analysis and reverse-engineering.? (Also, nice monospace font; is that Roboto?) I agree with your list of "useful properties"; storing existing JVM artifacts (such as CDS archives) as well as new JVM artifacts (heap object snapshots, AOT) are going to be required, and jimage is a candidate here (though not the only one.) Similarly, there's an evaluation to be done, for example, whether to update the CDS format to store more things (AOT, more general heap object storage), or to have separate stores for these, or to overhaul the format.? But whichever is chosen, embedding in jimage seems a possibility. The one assumption that I would quibble with is the suggestion for using jimage as an intermediate format in the condenser pipeline.? It seems credible that separate intermediate and final formats will be preferable to a one-size-fits-all, since the needs of the next condenser in the pipeline at build time are not likely to be the same as those of the VM at runtime, and formats like CDS are optimized for the VM to consume them, not to be, for example, easily queried and updated. Cheers, -Brian On 2/14/2023 8:39 AM, Severin Gehwolf wrote: > Hi, > > We have been looking at lib/modules (a.k.a jimage) as a potential > candidate format for Project Leyden. Along the way, I've documented how > the file is structured[1] and used in its current form. The document > discussing jimage in the context of Leyden is here: > > https://cr.openjdk.org/~sgehwolf/leyden/jimage_file_format_investigation_leyden.pdf > > Looking forward to your feedback! > > Thanks, > Severin > > [1]https://cr.openjdk.org/~sgehwolf/leyden/jimage_visualization_1.png > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Tue Feb 14 22:58:34 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Tue, 14 Feb 2023 14:58:34 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <871qmsbovj.fsf@oldenburg.str.redhat.com> References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> <871qmsbovj.fsf@oldenburg.str.redhat.com> Message-ID: On Tue, Feb 14, 2023 at 1:03 AM Florian Weimer wrote: > * Jiangli Zhou: > > > On Mon, Feb 13, 2023 at 1:58 AM Florian Weimer > wrote: > > > > * Jiangli Zhou: > > > > > 1. The executable image (see slide #10 ofa [1]) consists of three > > > sections: the ELF executable section (see slide #14), the JDK runtime > > > section (see slide #20, #21) and the JAR section (see slide #22). > > > > These sections are not ELF sections, right? > > > > Just to clarify that the ELF sections you referred to in the above are > > the sections within an ELF file > > (e.g. https://manpages.debian.org/stretch/manpages/elf.5.en.html), if > > my understanding is correct. The sections described for a hermetic > > Java image are indeed not ELF sections in that sense. An ELF file as a > > whole is encapsulated in the hermetic image at the beginning. We can > > use a better name (if ELF section may cause any confusions), > > e.g. executable section, to describe the section containing the ELF > > file. > > I wouldn't use ?section? or ?segment? in this context if it's not about > the ELF constructs. ELF doesn't use ?part? or ?appendix? as > terminology, so that would work. > Thanks. Alternatively, 'component' may also be used without potential confusion? > > > [from further down the thread] > > > > > Yeah, the loadLibrary and friends need to be able look up built-in > > > libraries in the executable (within the image ELF section). The > > > existing JDK code is already able to handle built-in libraries > > > (partially). Please see more details for built-in native support in > > > earlier comments. > > > > I believe that will require a custom glibc patch that has not been > > upstreamed. I think Google's approach is here: > > > > > > < > https://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlopen.c;h=faf7a48ea71df186b3581235bffcc7a3692f1325;hb=refs/heads/google/grte/v5-2.27/master#l95 > > > > > > > > The loadLibrary work for built-in native libraries (with JDK static > > support) does not require the glibc patch for dlopen_with_offset. > > Okay, but that means that Hotspot can't be re-linked or unbundled. > That's an interesting use case. Any specific requirements/benefits for re-linking an existing hermetic image with different hotspot code/version? >From our observations of production usages, change in JDK libraries or the VM would be deployed via new releases (including both JDK release and the application release). Those include different testing cycles/stages before the new binary reaches production. The process includes rebuilding the hermetic image. > > > There is a different proposed glibc interface for this: > > > > [PATCH v2 2/2] dlfcn,elf: implement dlmem() function [BZ #11767] > > < > https://sourceware.org/pipermail/libc-alpha/2023-February/145476.html> > > > > Maybe you could check if that interface could serve your needs as well? > > > > Thanks for pointing to dlmem(). So it looks like we could read the DSO > > into a buffer then load with dlmem(). Cool! The build ID and symbol > > file mapping could still be problematic? > > I don't think so, it's linked into the glibc dynamic loader data > structures like any other mapping. It probably depends on the tooling. > If it uses DT_DEBUG/_r_debug, it should be able to identify these > mappings even though they are not file-based. If the tooling uses > /proc/PID/maps and not _r_debug, that's of course a different matter. If I understand correctly from past (internal) discussions with the folks from the tooling side, the existing tools mostly have the assumption that the ELF header starts at the beginning of an ELF file (the hermetic Java image can be treated as an ELF by tools since that's at the beginning of the image). If we are going with supporting file embedded DSOs, it would require propagating the support in various tools (perf, gdb, lldb, ...). > > Note that dlmem is just a proposed new interface for now. > Thanks for that data point. Best, Jiangli > > Thanks, > Florian > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jianglizhou at google.com Tue Feb 14 23:53:42 2023 From: jianglizhou at google.com (Jiangli Zhou) Date: Tue, 14 Feb 2023 15:53:42 -0800 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <87wn4ka8qd.fsf@oldenburg.str.redhat.com> References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> <610a91ed-f0e8-ff70-f081-ece82fc4e7c2@oracle.com> <87cz6depvr.fsf@oldenburg.str.redhat.com> <87wn4ka8qd.fsf@oldenburg.str.redhat.com> Message-ID: On Tue, Feb 14, 2023 at 1:37 AM Florian Weimer wrote: > * Jiangli Zhou: > > > We also considered startup-time/install-time extraction. Based on the > > feedback from other language usages in real production, extraction has > > real production challenges in many cases, including (tmpfs) file > > system configuration/management issues, possible security > > vulnerabilities, temp space pollution, extraction conflicts, and > > etc. (thanks to the feedback from other language experts from their > > experiences!). Those make the extraction approach unattractive. > > I thought that OpenJDK has its own DSO-from-JAR extractor? > Do you have a pointer to the feature? > > There's memfd_create, which is currently an un-auditable trapdoor to the > world of self-modifying code (although I expect that will be closed off > eventually). It works even if /tmp, /dev/shm, etc. are all mounted > noexec. > > Experimenting with it suggests that GDB doesn't rely on link map data > exclusively. It gets somewhat confused and doesn't read the symbols: > > (gdb) info shared > From To Syms Read Shared Object Library > 0x00007f00a83a1700 0x00007f00a84f519d Yes /lib64/libc.so.6 > 0x00007f00a85720a0 0x00007f00a85980e5 Yes > /lib64/ld-linux-x86-64.so.2 > No /proc/589166/fd/3 > > This should work, but it does not. 8-( Even the non-debugging > ELF symbols are missing. > > The dlmem implementation posted to libc-alpha probably has even more > problems. I'm no longer convinced that the public link map (reachable > via _r_debug) has sufficient information for debuggers. > > But if we could fix these issues, the memfd_create approach could be a > viable replacement for extracting DSOs from JAR files (to turn this > slightly more on-topic). > AFAIK, there were some investigations/experiments done by others in Google on memfd_create for supporting file embedded DSOs (not Java specific). The concerns from the tooling side (about file offsets) still seem to be applicable with this approach. Best, Jiangli > > Thanks, > Florian > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ioi.lam at oracle.com Wed Feb 15 02:33:24 2023 From: ioi.lam at oracle.com (Ioi Lam) Date: Tue, 14 Feb 2023 18:33:24 -0800 Subject: File Format Investigation: jimage In-Reply-To: <471744e2-d638-c441-0e39-e4127c972371@oracle.com> References: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> <471744e2-d638-c441-0e39-e4127c972371@oracle.com> Message-ID: On 2/14/2023 1:50 PM, Brian Goetz wrote: > Nice analysis and reverse-engineering.? (Also, nice monospace font; is > that Roboto?) > > I agree with your list of "useful properties"; storing existing JVM > artifacts (such as CDS archives) as well as new JVM artifacts (heap > object snapshots, AOT) are going to be required, and jimage is a > candidate here (though not the only one.)? Similarly, there's an > evaluation to be done, for example, whether to update the CDS format > to store more things (AOT, more general heap object storage), or to > have separate stores for these, or to overhaul the format.? But > whichever is chosen, embedding in jimage seems a possibility. > > The one assumption that I would quibble with is the suggestion for > using jimage as an intermediate format in the condenser pipeline.? It > seems credible that separate intermediate and final formats will be > preferable to a one-size-fits-all, since the needs of the next > condenser in the pipeline at build time are not likely to be the same > as those of the VM at runtime, and formats like CDS are optimized for > the VM to consume them, not to be, for example, easily queried and > updated. > FYI, For debugging purposes, CDS can be generated with a map file that describes its contents in detail. One thing on my todo list is to generate an hprof file as part of the CDS dump. You can load it into an hprof viewer to examine the archived Java objects. But I agree that trying to extract individual elements from the CDS archive is not easy, and probably not worth doing. Thanks - Ioi > Cheers, > -Brian > > > > On 2/14/2023 8:39 AM, Severin Gehwolf wrote: >> Hi, >> >> We have been looking at lib/modules (a.k.a jimage) as a potential >> candidate format for Project Leyden. Along the way, I've documented how >> the file is structured[1] and used in its current form. The document >> discussing jimage in the context of Leyden is here: >> >> https://cr.openjdk.org/~sgehwolf/leyden/jimage_file_format_investigation_leyden.pdf >> >> Looking forward to your feedback! >> >> Thanks, >> Severin >> >> [1]https://cr.openjdk.org/~sgehwolf/leyden/jimage_visualization_1.png >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From heidinga at redhat.com Wed Feb 15 14:16:01 2023 From: heidinga at redhat.com (Dan Heidinga) Date: Wed, 15 Feb 2023 09:16:01 -0500 Subject: File Format Investigation: jimage In-Reply-To: <471744e2-d638-c441-0e39-e4127c972371@oracle.com> References: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> <471744e2-d638-c441-0e39-e4127c972371@oracle.com> Message-ID: On Tue, Feb 14, 2023 at 4:50 PM Brian Goetz wrote: > Nice analysis and reverse-engineering. (Also, nice monospace font; is > that Roboto?) > > I agree with your list of "useful properties"; storing existing JVM > artifacts (such as CDS archives) as well as new JVM artifacts (heap object > snapshots, AOT) are going to be required, and jimage is a candidate here > (though not the only one.) Similarly, there's an evaluation to be done, > for example, whether to update the CDS format to store more things (AOT, > more general heap object storage), or to have separate stores for these, or > to overhaul the format. But whichever is chosen, embedding in jimage seems > a possibility. > > The one assumption that I would quibble with is the suggestion for using > jimage as an intermediate format in the condenser pipeline. It seems > credible that separate intermediate and final formats will be preferable to > a one-size-fits-all, since the needs of the next condenser in the pipeline > at build time are not likely to be the same as those of the VM at runtime, > and formats like CDS are optimized for the VM to consume them, not to be, > for example, easily queried and updated. > "Intermediate format" doesn't quite capture our thinking here. The assumption was that starting from a JVM and a set of modules, we might apply some condensers (jlink being the tool for such activities today), and produce a resulting image. This image should both be runnable as is and also be usable as input for further condensation passes. Mark and I's discussion [0] indicated this was a goal at least for non-terminal condensers (ie: those that haven't "condensed all the way down to a platform-specific executable"). Does that mean that jimage (or whatever the chosen format ends up being) must be the intermediate form? Probably not but I think it does put a requirement on the system that condensed images need to be considered as valid inputs to the system. Were you thinking of requiring a separate step that converts condensed images to runnable ones? Where the second step in this process is always required to get a runnable result? { JDK + modules | condensed image } --> condensers --> condensed image condensed image --> runnable image --Dan [0] https://mail.openjdk.org/pipermail/leyden-dev/2022-October/000085.html > > > Cheers, > -Brian > > > > On 2/14/2023 8:39 AM, Severin Gehwolf wrote: > > Hi, > > We have been looking at lib/modules (a.k.a jimage) as a potential > candidate format for Project Leyden. Along the way, I've documented how > the file is structured[1] and used in its current form. The document > discussing jimage in the context of Leyden is here: > https://cr.openjdk.org/~sgehwolf/leyden/jimage_file_format_investigation_leyden.pdf > > Looking forward to your feedback! > > Thanks, > Severin > > [1] https://cr.openjdk.org/~sgehwolf/leyden/jimage_visualization_1.png > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed Feb 15 14:36:19 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 15 Feb 2023 09:36:19 -0500 Subject: File Format Investigation: jimage In-Reply-To: References: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> <471744e2-d638-c441-0e39-e4127c972371@oracle.com> Message-ID: <1fb77a82-5163-efca-b9d4-7f8a84472ad2@oracle.com> The devil is in the details, of course; different condensers may do different degrees of condensation.? You cited as your use case: > starting from a JVM and a set of modules, we might apply some > condensers (jlink being the tool for such activities today), and > produce a resulting image. The key word that is confusing us here is *some*; let's say you're applying condensers A, B, and C.? Should we produce a complete, runnable, binary application image with AppCDS archives and all that between A and B, and then again between B and C?? That's what I mean by "intermediate format". On 2/15/2023 9:16 AM, Dan Heidinga wrote: > > > On Tue, Feb 14, 2023 at 4:50 PM Brian Goetz > wrote: > > Nice analysis and reverse-engineering.? (Also, nice monospace > font; is that Roboto?) > > I agree with your list of "useful properties"; storing existing > JVM artifacts (such as CDS archives) as well as new JVM artifacts > (heap object snapshots, AOT) are going to be required, and jimage > is a candidate here (though not the only one.)? Similarly, there's > an evaluation to be done, for example, whether to update the CDS > format to store more things (AOT, more general heap object > storage), or to have separate stores for these, or to overhaul the > format.? But whichever is chosen, embedding in jimage seems a > possibility. > > The one assumption that I would quibble with is the suggestion for > using jimage as an intermediate format in the condenser pipeline.? > It seems credible that separate intermediate and final formats > will be preferable to a one-size-fits-all, since the needs of the > next condenser in the pipeline at build time are not likely to be > the same as those of the VM at runtime, and formats like CDS are > optimized for the VM to consume them, not to be, for example, > easily queried and updated. > > > "Intermediate format" doesn't quite capture our thinking here.? The > assumption was that starting from a JVM and a set of modules, we might > apply some condensers (jlink being the tool for such activities > today), and produce a resulting image.? This image should both be > runnable as is and also be usable as input for further condensation > passes.? Mark and I's discussion [0] indicated this was a goal at > least for non-terminal condensers?(ie: those that haven't "condensed > all the way down to a platform-specific executable"). > > Does that mean that jimage (or whatever the chosen format ends up > being) must be the intermediate form?? Probably not but I think it > does put a requirement on the system that condensed images need to be > considered as valid inputs to the system. > > Were you thinking of requiring a separate step that converts condensed > images to runnable ones?? Where the second step in this process is > always required to get a runnable result? > > { JDK?+ modules | condensed image }? --> condensers --> condensed image > condensed image --> runnable image > > --Dan > > [0] https://mail.openjdk.org/pipermail/leyden-dev/2022-October/000085.html > > > > Cheers, > -Brian > > > > On 2/14/2023 8:39 AM, Severin Gehwolf wrote: >> Hi, >> >> We have been looking at lib/modules (a.k.a jimage) as a potential >> candidate format for Project Leyden. Along the way, I've documented how >> the file is structured[1] and used in its current form. The document >> discussing jimage in the context of Leyden is here: >> >> https://cr.openjdk.org/~sgehwolf/leyden/jimage_file_format_investigation_leyden.pdf >> >> Looking forward to your feedback! >> >> Thanks, >> Severin >> >> [1]https://cr.openjdk.org/~sgehwolf/leyden/jimage_visualization_1.png >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From heidinga at redhat.com Wed Feb 15 14:48:40 2023 From: heidinga at redhat.com (Dan Heidinga) Date: Wed, 15 Feb 2023 09:48:40 -0500 Subject: File Format Investigation: jimage In-Reply-To: <1fb77a82-5163-efca-b9d4-7f8a84472ad2@oracle.com> References: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> <471744e2-d638-c441-0e39-e4127c972371@oracle.com> <1fb77a82-5163-efca-b9d4-7f8a84472ad2@oracle.com> Message-ID: On Wed, Feb 15, 2023 at 9:36 AM Brian Goetz wrote: > The devil is in the details, of course; different condensers may do > different degrees of condensation. You cited as your use case: > > starting from a JVM and a set of modules, we might apply some condensers > (jlink being the tool for such activities today), and produce a resulting > image. > > > The key word that is confusing us here is *some*; let's say you're > applying condensers A, B, and C. Should we produce a complete, runnable, > binary application image with AppCDS archives and all that between A and B, > and then again between B and C? That's what I mean by "intermediate > format". > > I think we're on the same page. My expectation was I'd have a runnable image at the end of A->B->C and could then, assuming non-terminal condensers, either execute it or feed it through a new condenser pass of D->E->F. --Dan > > On 2/15/2023 9:16 AM, Dan Heidinga wrote: > > > > On Tue, Feb 14, 2023 at 4:50 PM Brian Goetz > wrote: > >> Nice analysis and reverse-engineering. (Also, nice monospace font; is >> that Roboto?) >> >> I agree with your list of "useful properties"; storing existing JVM >> artifacts (such as CDS archives) as well as new JVM artifacts (heap object >> snapshots, AOT) are going to be required, and jimage is a candidate here >> (though not the only one.) Similarly, there's an evaluation to be done, >> for example, whether to update the CDS format to store more things (AOT, >> more general heap object storage), or to have separate stores for these, or >> to overhaul the format. But whichever is chosen, embedding in jimage seems >> a possibility. >> >> The one assumption that I would quibble with is the suggestion for using >> jimage as an intermediate format in the condenser pipeline. It seems >> credible that separate intermediate and final formats will be preferable to >> a one-size-fits-all, since the needs of the next condenser in the pipeline >> at build time are not likely to be the same as those of the VM at runtime, >> and formats like CDS are optimized for the VM to consume them, not to be, >> for example, easily queried and updated. >> > > "Intermediate format" doesn't quite capture our thinking here. The > assumption was that starting from a JVM and a set of modules, we might > apply some condensers (jlink being the tool for such activities today), and > produce a resulting image. This image should both be runnable as is and > also be usable as input for further condensation passes. Mark and I's > discussion [0] indicated this was a goal at least for non-terminal > condensers (ie: those that haven't "condensed all the way down to a > platform-specific executable"). > > Does that mean that jimage (or whatever the chosen format ends up being) > must be the intermediate form? Probably not but I think it does put a > requirement on the system that condensed images need to be considered as > valid inputs to the system. > > Were you thinking of requiring a separate step that converts condensed > images to runnable ones? Where the second step in this process is always > required to get a runnable result? > > { JDK + modules | condensed image } --> condensers --> condensed image > condensed image --> runnable image > > --Dan > > [0] https://mail.openjdk.org/pipermail/leyden-dev/2022-October/000085.html > > >> >> >> Cheers, >> -Brian >> >> >> >> On 2/14/2023 8:39 AM, Severin Gehwolf wrote: >> >> Hi, >> >> We have been looking at lib/modules (a.k.a jimage) as a potential >> candidate format for Project Leyden. Along the way, I've documented how >> the file is structured[1] and used in its current form. The document >> discussing jimage in the context of Leyden is here: >> https://cr.openjdk.org/~sgehwolf/leyden/jimage_file_format_investigation_leyden.pdf >> >> Looking forward to your feedback! >> >> Thanks, >> Severin >> >> [1] https://cr.openjdk.org/~sgehwolf/leyden/jimage_visualization_1.png >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed Feb 15 15:30:09 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 15 Feb 2023 10:30:09 -0500 Subject: File Format Investigation: jimage In-Reply-To: References: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> <471744e2-d638-c441-0e39-e4127c972371@oracle.com> <1fb77a82-5163-efca-b9d4-7f8a84472ad2@oracle.com> Message-ID: <6f05b368-8057-ad97-b0cb-c17250ef8d6b@oracle.com> I think we're on the same page about "what should you be able to do", though clearly we need some more refined terminology for describing it, since there are a number of possible states. On 2/15/2023 9:48 AM, Dan Heidinga wrote: > > > On Wed, Feb 15, 2023 at 9:36 AM Brian Goetz > wrote: > > The devil is in the details, of course; different condensers may > do different degrees of condensation.? You cited as your use case: > >> starting from a JVM and a set of modules, we might apply some >> condensers (jlink being the tool for such activities today), and >> produce a resulting image. > > The key word that is confusing us here is *some*; let's say you're > applying condensers A, B, and C. Should we produce a complete, > runnable, binary application image with AppCDS archives and all > that between A and B, and then again between B and C? That's what > I mean by "intermediate format". > > > I think we're on the same page.? My expectation was I'd have a > runnable image at the end of A->B->C and could then, assuming > non-terminal condensers, either execute it or feed it through a new > condenser pass of D->E->F. > > --Dan > > > On 2/15/2023 9:16 AM, Dan Heidinga wrote: >> >> >> On Tue, Feb 14, 2023 at 4:50 PM Brian Goetz >> wrote: >> >> Nice analysis and reverse-engineering.? (Also, nice monospace >> font; is that Roboto?) >> >> I agree with your list of "useful properties"; storing >> existing JVM artifacts (such as CDS archives) as well as new >> JVM artifacts (heap object snapshots, AOT) are going to be >> required, and jimage is a candidate here (though not the only >> one.) Similarly, there's an evaluation to be done, for >> example, whether to update the CDS format to store more >> things (AOT, more general heap object storage), or to have >> separate stores for these, or to overhaul the format.? But >> whichever is chosen, embedding in jimage seems a possibility. >> >> The one assumption that I would quibble with is the >> suggestion for using jimage as an intermediate format in the >> condenser pipeline.? It seems credible that separate >> intermediate and final formats will be preferable to a >> one-size-fits-all, since the needs of the next condenser in >> the pipeline at build time are not likely to be the same as >> those of the VM at runtime, and formats like CDS are >> optimized for the VM to consume them, not to be, for example, >> easily queried and updated. >> >> >> "Intermediate format" doesn't quite capture our thinking here.? >> The assumption was that starting from a JVM and a set of modules, >> we might apply some condensers (jlink being the tool for such >> activities today), and produce a resulting image. This image >> should both be runnable as is and also be usable as input for >> further condensation passes.? Mark and I's discussion [0] >> indicated this was a goal at least for non-terminal >> condensers?(ie: those that haven't "condensed all the way down to >> a platform-specific executable"). >> >> Does that mean that jimage (or whatever the chosen format ends up >> being) must be the intermediate form?? Probably not but I think >> it does put a requirement on the system that condensed images >> need to be considered as valid inputs to the system. >> >> Were you thinking of requiring a separate step that converts >> condensed images to runnable ones? Where the second step in this >> process is always required to get a runnable result? >> >> { JDK?+ modules | condensed image }? --> condensers --> condensed >> image >> condensed image --> runnable image >> >> --Dan >> >> [0] >> https://mail.openjdk.org/pipermail/leyden-dev/2022-October/000085.html >> >> >> >> Cheers, >> -Brian >> >> >> >> On 2/14/2023 8:39 AM, Severin Gehwolf wrote: >>> Hi, >>> >>> We have been looking at lib/modules (a.k.a jimage) as a potential >>> candidate format for Project Leyden. Along the way, I've documented how >>> the file is structured[1] and used in its current form. The document >>> discussing jimage in the context of Leyden is here: >>> >>> https://cr.openjdk.org/~sgehwolf/leyden/jimage_file_format_investigation_leyden.pdf >>> >>> Looking forward to your feedback! >>> >>> Thanks, >>> Severin >>> >>> [1]https://cr.openjdk.org/~sgehwolf/leyden/jimage_visualization_1.png >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sgehwolf at redhat.com Fri Feb 17 11:44:20 2023 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Fri, 17 Feb 2023 12:44:20 +0100 Subject: File Format Investigation: jimage In-Reply-To: <471744e2-d638-c441-0e39-e4127c972371@oracle.com> References: <4a1ea6468eb22994986dc6ce01a2350d1f57a6e3.camel@redhat.com> <471744e2-d638-c441-0e39-e4127c972371@oracle.com> Message-ID: On Tue, 2023-02-14 at 16:50 -0500, Brian Goetz wrote: > ?Nice analysis and reverse-engineering.? (Also, nice monospace font; > is that Roboto?)? Thanks. The font is Roboto Mono. > ?I agree with your list of "useful properties"; storing existing JVM > artifacts (such as CDS archives) as well as new JVM artifacts (heap > object snapshots, AOT) are going to be required, and jimage is a > candidate here (though not the only one.)? Similarly, there's an > evaluation to be done, for example, whether to update the CDS format > to store more things (AOT, more general heap object storage), or to > have separate stores for these, or to overhaul the format.? But > whichever is chosen, embedding in jimage seems a possibility.? > ? > ?The one assumption that I would quibble with is the suggestion for > using jimage as an intermediate format in the condenser pipeline.? It > seems credible that separate intermediate and final formats will be > preferable to a one-size-fits-all, since the needs of the next > condenser in the pipeline at build time are not likely to be the same > as those of the VM at runtime, and formats like CDS are optimized for > the VM to consume them, not to be, for example, easily queried and > updated.? Perhaps it would be useful to define "format" in this context. Is "format" a single file? Could it be many? Perhaps so. In terms of composablility it doesn't seem strictly necessary as the current way how jlink (or whatever the future interface to drive the condenser pipeline is) works, is to also include transformations for binaries and shared objects. Thanks, Severin From ron.pressler at oracle.com Mon Feb 20 09:49:28 2023 From: ron.pressler at oracle.com (Ron Pressler) Date: Mon, 20 Feb 2023 09:49:28 +0000 Subject: Hermetic Java (static image packaging/formatting) investigation and proposal In-Reply-To: <871qmsbovj.fsf@oldenburg.str.redhat.com> References: <87zg9hga3w.fsf@oldenburg.str.redhat.com> <871qmsbovj.fsf@oldenburg.str.redhat.com> Message-ID: <3112CFAD-92D9-447F-B8CA-DBDED54868D7@oracle.com> > On 14 Feb 2023, at 09:03, Florian Weimer wrote: > > Okay, but that means that Hotspot can't be re-linked or unbundled. HotSpot is tightly coupled to the JDK core libraries, and those are bundled by jlink, too. Perhaps that this deployment model isn?t appropriate for *all* situations, but it is in line with the jlink approach that?s already offered by the JDK. ? Ron From mike at hydraulic.software Fri Feb 24 14:45:53 2023 From: mike at hydraulic.software (Mike Hearn) Date: Fri, 24 Feb 2023 15:45:53 +0100 Subject: Notes on packaging of native code in libraries Message-ID: Hello, Recently there was a discussion of hermetic Java and how native libraries are packaged in Google's solution. The approach is Linux specific but once you leave that OS new issues emerge. We've just published a blog post that explores the problems that arise when distributing Java apps to platforms that require code signing: https://hydraulic.software/blog/11-in-jar-signing.html Conveyor is a build tool that layers on top of jlink and it does extensive work to turn JARs into something that can be shipped to Mac/Windows users successfully. The blog post discusses some of these challenges, which any approach to static Java will also face (assuming it's supported on more than just Linux of course). The core issues are related to code signing, and the practice of extracting libraries on the fly from JARs to caches or temp directories. Conveyor has two modes, one which does this extraction ahead of time (but many libraries don't expect this and must be explicitly configured via system properties, or they just break), and the other which code signs libraries inside the JARs. The latter is less likely to break apps but yields other problems. Neither approach is perfect. Especially once Panama ships the Java ecosystem could strongly benefit from a standardization of how native components are bundled into and loaded from libraries, as current build systems and the JVM tooling don't have much to say on the topic. The result is a lot of wheel reinvention across the ecosystem in the form of NativeLibraryLoader.java classes, always unique per project, and a bunch of bugs / developer friction that doesn't need to happen. The good news is that all this would be very cheap to improve. All that's needed is: - A defined layout for JARs (or JMODs) that standardizes where to place native libraries given an OS and CPU architecture. - Tooling that extracts native code to a user-specified directory that's then appended to the java.library.path at runtime (e.g. a flag to the java launcher?), so that once build systems learn to pass this flag or do the extraction themselves library authors can just deprecate and eventually remove all their custom loader code (which is large, complex, copy/pasted between projects and inconsistent). - Support for that mechanism in jlink. The current JMOD mechanism improved things over the prior situation, but unfortunately doesn't quite supply everything needed. A solution that works with JARs and supports multiple libraries in one JAR would be easily adopted. -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Fri Feb 24 15:09:45 2023 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 24 Feb 2023 15:09:45 +0000 Subject: Notes on packaging of native code in libraries In-Reply-To: References: Message-ID: On 24/02/2023 14:45, Mike Hearn wrote: > Especially once Panama ships the Java ecosystem could strongly benefit > from a standardization of how native components are bundled into and > loaded from libraries, as current build systems?and the JVM tooling > don't have much to say on the topic. The result is a lot of wheel > reinvention across the ecosystem in the form of > NativeLibraryLoader.java classes, always unique per project, and a > bunch of bugs / developer friction that doesn't need to happen. I tend to agree with the overall assessment. Shipping native libraries with Java projects is a known pain point, and it would be nice to have some solution for that. That being said, while I'm aware that the best way to make things work in today's world is by shipping native libraries in a jar, and then extract them _somewhere_, so that they can be loaded with `System::loadLibrary`, I'm not sure how much that can be viewed as a full solution, rather than a workaround. I can imagine cases where extracting libraries into a custom folder is not feasible (e.g. because of missing permissions). My general feeling is that, with jars and native libraries it's like trying to fit a round peg in a square hole: surely you can devise some pragmatic solution which makes things sort of work, but what you get is always a little brittle. If you look at what we did for jextract [1], the approach we used was different: jextract is written entirely in Java, but has a dependency (via Foreign Function & Memory API) on libclang. When we build jextract, we create a jmod [2] for jextract, with the native library for libclang in the right place. We then create a JDK image which contains jdk.compiler, java.base and the newly created jextract module. The resulting JDK will have the libraries in the right place. This means that we can provide a launcher simply by calling jextract's entry point using the custom JDK image. You can run jextract and run all jextract tests against this custom image, which then requires zero extra custom arguments passed on the command line (because the native libraries are added in the right place already). An approach such as this seems more promising than doing heroics with jarfiles, at least for applications, and one that could be more amenable to things like code signing (in jextract we don't do this, but I don't see why that could not be added). Maurizio [1] - https://jdk.java.net/jextract/ [2] - https://github.com/openjdk/jextract/blob/master/build.gradle > > The good news is that all this would be very cheap to improve. All > that's needed is: > > * A defined layout for JARs (or JMODs) that standardizes?where to > place native libraries given an OS and CPU architecture. > > * Tooling that extracts native code to a user-specified directory > that's then appended to the java.library.path at runtime (e.g. a > flag to the java launcher?), so that once build systems learn to > pass this flag or do the extraction themselves library authors can > just deprecate and eventually remove all their custom loader code > (which is large, complex, copy/pasted between projects and > inconsistent). > > * Support for that mechanism in jlink. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mike at hydraulic.software Fri Feb 24 16:59:52 2023 From: mike at hydraulic.software (Mike Hearn) Date: Fri, 24 Feb 2023 17:59:52 +0100 Subject: Notes on packaging of native code in libraries In-Reply-To: References: Message-ID: Thanks! Yes creating JMODs is one way to do it, but if you were to distribute jextract as a library and not just an application you'd get user complaints because it'd take more work to consume: - JMODs are platform specific but build tools don't make it easy to select the right artifacts based on platforms. You can do it but it often requires custom Maven/Gradle plugins and such. - You can't put JMODs on the module path so users would now need to run jlink to get a JDK they could use, but build tools don't invoke jlink during the normal development cycle and don't easily support switching which JDK they use half way through based on the output of build tasks (maybe they should but last time I tried, they don't). You could write extra plugins to teach them to do that maybe, but then you'd hit performance problems - jlinking is a fairly heavy and slow operation, and doesn't cache anything. All this complexity is why some vendor JDKs pre-jlink JavaFX. - It requires libraries to be modular and jlinkable. Sadly this is often quite challenging :( e.g. out of the box a vanilla Spring Boot Web app can't be linked because the module graph is invalid. The Spring guys know and don't plan to fix it. See https://github.com/spring-projects/spring-boot/issues/33942 So this runs into a fundamental question that Jigsaw never really resolved and maybe Leyden needs to: is jlink meant to be a last step optimization process you run before distribution (today, yes) or is it meant to be an integrated part of the compile-and-test cycle? If it's the former you can get bugs that only appear at distribution time. If it's the latter then it needs a different performance and compatibility model. GraalVM Native Image faces the same problem: it's slow to compile and introduces new bugs, so it's tough to integrate it into the standard development and testing process. Ordinary HotSpot with a classpath/module path is so great for development because changing things about your app is just so darn fast, users are loath to lose that. Hence the proliferation of libraries that extract code on the fly. It's inelegant and creates other problems but it preserves the ultra-fast build loops that people love so much, and doesn't require special support from build systems. Sponsored Link: maybe jextract should be distributed with Conveyor ;) It'd be convenient to have installs that can keep themselves up to date, added to the path automatically etc. On Fri, 24 Feb 2023 at 16:09, Maurizio Cimadamore < maurizio.cimadamore at oracle.com> wrote: > > On 24/02/2023 14:45, Mike Hearn wrote: > > Especially once Panama ships the Java ecosystem could strongly benefit > from a standardization of how native components are bundled into and loaded > from libraries, as current build systems and the JVM tooling don't have > much to say on the topic. The result is a lot of wheel reinvention across > the ecosystem in the form of NativeLibraryLoader.java classes, always > unique per project, and a bunch of bugs / developer friction that doesn't > need to happen. > > I tend to agree with the overall assessment. Shipping native libraries > with Java projects is a known pain point, and it would be nice to have some > solution for that. That being said, while I'm aware that the best way to > make things work in today's world is by shipping native libraries in a jar, > and then extract them _somewhere_, so that they can be loaded with > `System::loadLibrary`, I'm not sure how much that can be viewed as a full > solution, rather than a workaround. I can imagine cases where extracting > libraries into a custom folder is not feasible (e.g. because of missing > permissions). My general feeling is that, with jars and native libraries > it's like trying to fit a round peg in a square hole: surely you can devise > some pragmatic solution which makes things sort of work, but what you get > is always a little brittle. > > If you look at what we did for jextract [1], the approach we used was > different: jextract is written entirely in Java, but has a dependency (via > Foreign Function & Memory API) on libclang. When we build jextract, we > create a jmod [2] for jextract, with the native library for libclang in the > right place. We then create a JDK image which contains jdk.compiler, > java.base and the newly created jextract module. The resulting JDK will > have the libraries in the right place. This means that we can provide a > launcher simply by calling jextract's entry point using the custom JDK > image. You can run jextract and run all jextract tests against this custom > image, which then requires zero extra custom arguments passed on the > command line (because the native libraries are added in the right place > already). > > An approach such as this seems more promising than doing heroics with > jarfiles, at least for applications, and one that could be more amenable to > things like code signing (in jextract we don't do this, but I don't see why > that could not be added). > > Maurizio > > [1] - https://jdk.java.net/jextract/ > [2] - https://github.com/openjdk/jextract/blob/master/build.gradle > > > The good news is that all this would be very cheap to improve. All that's > needed is: > > - A defined layout for JARs (or JMODs) that standardizes where to > place native libraries given an OS and CPU architecture. > > - Tooling that extracts native code to a user-specified directory > that's then appended to the java.library.path at runtime (e.g. a flag to > the java launcher?), so that once build systems learn to pass this flag or > do the extraction themselves library authors can just deprecate and > eventually remove all their custom loader code (which is large, complex, > copy/pasted between projects and inconsistent). > > - Support for that mechanism in jlink. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Fri Feb 24 18:21:12 2023 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 24 Feb 2023 18:21:12 +0000 Subject: Notes on packaging of native code in libraries In-Reply-To: References: Message-ID: <13424b2a-b21f-8791-913a-4ceb885beeae@oracle.com> On 24/02/2023 16:59, Mike Hearn wrote: > Thanks! Yes creating JMODs is one way to do it, but if you were to > distribute jextract as a library and not just an application you'd get > user complaints because it'd take more work to consume: Yep - I agree libraries are a different beast (in my email I specifically mentioned "application"). > > * JMODs are platform specific but build tools don't make it easy to > select the right artifacts based on platforms. You can do it but > it often requires custom Maven/Gradle plugins and such. > > * You can't put JMODs on the module path so users would now need to > run jlink to get?a JDK they could use, but build tools don't > invoke jlink during the normal development cycle and don't easily > support?switching which JDK they use half way through based on the > output of build tasks (maybe they should but last time I tried, > they don't). You could write extra plugins to teach them to do > that maybe, but then you'd hit performance problems - jlinking is > a fairly heavy and slow operation, and doesn't cache anything. All > this complexity is why some vendor JDKs pre-jlink JavaFX. > > * It requires libraries to be modular and jlinkable. Sadly this is > often quite challenging :( e.g. out of the box a vanilla Spring > Boot Web app can't be linked?because the module graph is invalid. > The Spring guys know and don't plan to fix it. See > https://github.com/spring-projects/spring-boot/issues/33942 > > It's true that jmod are mostly designed to be inputs to jlink. That said, my general feeling is that tools such as jlink are being under-used and, when used correctly they can simplify processes quite a bit. So perhaps investing in that direction might provide better dividends. > So this runs into a fundamental question that Jigsaw never really > resolved and maybe Leyden needs to:?is jlink meant to be a last step > optimization process you run before distribution (today, yes) or is it > meant to be an integrated part of the compile-and-test cycle? I personally think that if jlink was used as part of compile-and-test cycle it would be for the betterment of mankind :-) I can't count the number of times where I was staring at a maven/gradle build file in confusion, trying to understand why a certain dependency wasn't being pulled in, or why the IDE had a "view" of the world that didn't match the one provided by Maven/Gradle. While IDEs have become quite good at this, there is still a lot of friction which, IMHO completely goes away if the artifact of a build is not just a bunch of classes, but a full JDK image. But, perhaps, we're getting away from the scope of this mailing list :-) Maurizio > If it's the former you can get bugs that only appear at distribution > time. If it's the latter then it needs a different performance and > compatibility model. GraalVM Native Image faces the same problem: it's > slow to compile and introduces new bugs, so it's tough to integrate it > into the standard development and testing process. Ordinary HotSpot > with a classpath/module path is so great for development because > changing things about your app is just so darn fast, users are loath > to lose that. Hence the proliferation of libraries that extract code > on the fly. It's inelegant and creates other problems but it preserves > the ultra-fast build loops that people love so much, and doesn't > require special support from build systems. I have jextract setup with jlink for my daily work and honestly I can't complain about it being "slow". I can change code and run all tests and it feels quite instant and natural (and with very very little fiddling). The main issue is that all the build tools we know and love (Maven, Gradle) are _not_ designed around the idea of linked images - which makes it very difficult to do what we did (and I understand why somebody might look elsewhere rather than picking a fight with gradle to try and run jlink, and then use the generated image to run tests). > > Sponsored Link: maybe jextract should be distributed with Conveyor ;) > It'd be convenient to have installs that can keep themselves up to > date, added to the path automatically etc. Hehe Maurizio > > > On Fri, 24 Feb 2023 at 16:09, Maurizio Cimadamore > wrote: > > > On 24/02/2023 14:45, Mike Hearn wrote: >> Especially once Panama ships the Java ecosystem could strongly >> benefit from a standardization of how native components are >> bundled into and loaded from libraries, as current build >> systems?and the JVM tooling don't have much to say on the topic. >> The result is a lot of wheel reinvention across the ecosystem in >> the form of NativeLibraryLoader.java classes, always unique per >> project, and a bunch of bugs / developer friction that doesn't >> need to happen. > > I tend to agree with the overall assessment. Shipping native > libraries with Java projects is a known pain point, and it would > be nice to have some solution for that. That being said, while I'm > aware that the best way to make things work in today's world is by > shipping native libraries in a jar, and then extract them > _somewhere_, so that they can be loaded with > `System::loadLibrary`, I'm not sure how much that can be viewed as > a full solution, rather than a workaround. I can imagine cases > where extracting libraries into a custom folder is not feasible > (e.g. because of missing permissions). My general feeling is that, > with jars and native libraries it's like trying to fit a round peg > in a square hole: surely you can devise some pragmatic solution > which makes things sort of work, but what you get is always a > little brittle. > > If you look at what we did for jextract [1], the approach we used > was different: jextract is written entirely in Java, but has a > dependency (via Foreign Function & Memory API) on libclang. When > we build jextract, we create a jmod [2] for jextract, with the > native library for libclang in the right place. We then create a > JDK image which contains jdk.compiler, java.base and the newly > created jextract module. The resulting JDK will have the libraries > in the right place. This means that we can provide a launcher > simply by calling jextract's entry point using the custom JDK > image. You can run jextract and run all jextract tests against > this custom image, which then requires zero extra custom arguments > passed on the command line (because the native libraries are added > in the right place already). > > An approach such as this seems more promising than doing heroics > with jarfiles, at least for applications, and one that could be > more amenable to things like code signing (in jextract we don't do > this, but I don't see why that could not be added). > > Maurizio > > [1] - https://jdk.java.net/jextract/ > > [2] - https://github.com/openjdk/jextract/blob/master/build.gradle > > >> >> The good news is that all this would be very cheap to improve. >> All that's needed is: >> >> * A defined layout for JARs (or JMODs) that standardizes?where >> to place native libraries given an OS and CPU architecture. >> >> * Tooling that extracts native code to a user-specified >> directory that's then appended to the java.library.path at >> runtime (e.g. a flag to the java launcher?), so that once >> build systems learn to pass this flag or do the extraction >> themselves library authors can just deprecate and eventually >> remove all their custom loader code (which is large, complex, >> copy/pasted between projects and inconsistent). >> >> * Support for that mechanism in jlink. >> -------------- next part -------------- An HTML attachment was scrubbed... URL: