26
26
import java .util .Set ;
27
27
import java .util .TreeMap ;
28
28
import java .util .function .Function ;
29
+ import java .util .function .Supplier ;
29
30
31
+ import org .gradle .api .GradleException ;
30
32
import org .gradle .api .file .CopySpec ;
31
33
import org .gradle .api .file .FileCopyDetails ;
32
34
import org .gradle .api .file .FileTreeElement ;
36
38
import org .gradle .api .internal .file .copy .FileCopyDetailsInternal ;
37
39
import org .gradle .api .java .archives .Attributes ;
38
40
import org .gradle .api .java .archives .Manifest ;
41
+ import org .gradle .api .provider .Property ;
39
42
import org .gradle .api .specs .Spec ;
40
43
import org .gradle .api .specs .Specs ;
41
44
import org .gradle .api .tasks .WorkResult ;
42
45
import org .gradle .api .tasks .bundling .Jar ;
43
46
import org .gradle .api .tasks .util .PatternSet ;
47
+ import org .gradle .util .GradleVersion ;
44
48
45
49
/**
46
50
* Support class for implementations of {@link BootArchive}.
@@ -114,8 +118,8 @@ CopyAction createCopyAction(Jar jar, LayerResolver layerResolver, String layerTo
114
118
File output = jar .getArchiveFile ().get ().getAsFile ();
115
119
Manifest manifest = jar .getManifest ();
116
120
boolean preserveFileTimestamps = jar .isPreserveFileTimestamps ();
117
- Integer dirMode = jar . getDirMode ();
118
- Integer fileMode = jar . getFileMode ();
121
+ Integer dirMode = getDirMode (jar );
122
+ Integer fileMode = getFileMode (jar );
119
123
boolean includeDefaultLoader = isUsingDefaultLoader (jar );
120
124
Spec <FileTreeElement > requiresUnpack = this .requiresUnpack .getAsSpec ();
121
125
Spec <FileTreeElement > exclusions = this .exclusions .getAsExcludeSpec ();
@@ -129,6 +133,46 @@ CopyAction createCopyAction(Jar jar, LayerResolver layerResolver, String layerTo
129
133
return jar .isReproducibleFileOrder () ? new ReproducibleOrderingCopyAction (action ) : action ;
130
134
}
131
135
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
+
132
176
private boolean isUsingDefaultLoader (Jar jar ) {
133
177
return DEFAULT_LAUNCHER_CLASSES .contains (jar .getManifest ().getAttributes ().get ("Main-Class" ));
134
178
}
0 commit comments