2626import java .util .Set ;
2727import java .util .TreeMap ;
2828import java .util .function .Function ;
29+ import java .util .function .Supplier ;
2930
31+ import org .gradle .api .GradleException ;
3032import org .gradle .api .file .CopySpec ;
3133import org .gradle .api .file .FileCopyDetails ;
3234import org .gradle .api .file .FileTreeElement ;
3638import org .gradle .api .internal .file .copy .FileCopyDetailsInternal ;
3739import org .gradle .api .java .archives .Attributes ;
3840import org .gradle .api .java .archives .Manifest ;
41+ import org .gradle .api .provider .Property ;
3942import org .gradle .api .specs .Spec ;
4043import org .gradle .api .specs .Specs ;
4144import org .gradle .api .tasks .WorkResult ;
4245import org .gradle .api .tasks .bundling .Jar ;
4346import org .gradle .api .tasks .util .PatternSet ;
47+ import org .gradle .util .GradleVersion ;
4448
4549/**
4650 * Support class for implementations of {@link BootArchive}.
@@ -114,8 +118,8 @@ CopyAction createCopyAction(Jar jar, LayerResolver layerResolver, String layerTo
114118 File output = jar .getArchiveFile ().get ().getAsFile ();
115119 Manifest manifest = jar .getManifest ();
116120 boolean preserveFileTimestamps = jar .isPreserveFileTimestamps ();
117- Integer dirMode = jar . getDirMode ();
118- Integer fileMode = jar . getFileMode ();
121+ Integer dirMode = getDirMode (jar );
122+ Integer fileMode = getFileMode (jar );
119123 boolean includeDefaultLoader = isUsingDefaultLoader (jar );
120124 Spec <FileTreeElement > requiresUnpack = this .requiresUnpack .getAsSpec ();
121125 Spec <FileTreeElement > exclusions = this .exclusions .getAsExcludeSpec ();
@@ -129,6 +133,46 @@ CopyAction createCopyAction(Jar jar, LayerResolver layerResolver, String layerTo
129133 return jar .isReproducibleFileOrder () ? new ReproducibleOrderingCopyAction (action ) : action ;
130134 }
131135
136+ private Integer getDirMode (CopySpec copySpec ) {
137+ return getMode (copySpec , "getDirPermissions" , copySpec ::getDirMode );
138+ }
139+
140+ private Integer getFileMode (CopySpec copySpec ) {
141+ return getMode (copySpec , "getFilePermissions" , copySpec ::getFileMode );
142+ }
143+
144+ @ SuppressWarnings ("unchecked" )
145+ private Integer getMode (CopySpec copySpec , String methodName , Supplier <Integer > fallback ) {
146+ if (GradleVersion .current ().compareTo (GradleVersion .version ("8.3" )) >= 0 ) {
147+ try {
148+ Object filePermissions = ((Property <Object >) copySpec .getClass ().getMethod (methodName ).invoke (copySpec ))
149+ .getOrNull ();
150+ return getMode (filePermissions );
151+ }
152+ catch (Exception ex ) {
153+ throw new GradleException ("Failed to get permissions" , ex );
154+ }
155+ }
156+ return fallback .get ();
157+ }
158+
159+ private Integer getMode (Object permissions ) throws Exception {
160+ if (permissions == null ) {
161+ return null ;
162+ }
163+ String user = asIntegerString (permissions .getClass ().getMethod ("getUser" ).invoke (permissions ));
164+ String group = asIntegerString (permissions .getClass ().getMethod ("getGroup" ).invoke (permissions ));
165+ String other = asIntegerString (permissions .getClass ().getMethod ("getOther" ).invoke (permissions ));
166+ return Integer .parseInt ("0" + user + group + other , 8 );
167+ }
168+
169+ private String asIntegerString (Object permissions ) throws Exception {
170+ boolean read = (boolean ) permissions .getClass ().getMethod ("getRead" ).invoke (permissions );
171+ boolean write = (boolean ) permissions .getClass ().getMethod ("getWrite" ).invoke (permissions );
172+ boolean execute = (boolean ) permissions .getClass ().getMethod ("getExecute" ).invoke (permissions );
173+ return Integer .toString (((read ) ? 4 : 0 ) + ((write ) ? 2 : 0 ) + ((execute ) ? 1 : 0 ));
174+ }
175+
132176 private boolean isUsingDefaultLoader (Jar jar ) {
133177 return DEFAULT_LAUNCHER_CLASSES .contains (jar .getManifest ().getAttributes ().get ("Main-Class" ));
134178 }
0 commit comments