1
- /*
2
- * This file is part of ZipExtractor.
3
- * Copyright (C) 2016-2020 Daniel D. Scalzi <https://github.com/dscalzi/ZipExtractor>
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU Affero General Public License as
7
- * published by the Free Software Foundation, either version 3 of the
8
- * License, or (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU Affero General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU Affero General Public License
16
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
- */
18
-
19
- package com .dscalzi .zipextractor .core .provider ;
1
+ /*
2
+ * This file is part of ZipExtractor.
3
+ * Copyright (C) 2016-2020 Daniel D. Scalzi <https://github.com/dscalzi/ZipExtractor>
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU Affero General Public License as
7
+ * published by the Free Software Foundation, either version 3 of the
8
+ * License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU Affero General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License
16
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ package com .dscalzi .zipextractor .core .provider ;
20
20
21
21
import java .io .File ;
22
22
import java .io .FileOutputStream ;
23
23
import java .io .IOException ;
24
24
import java .io .OutputStream ;
25
+ import java .lang .reflect .InvocationTargetException ;
26
+ import java .lang .reflect .Method ;
25
27
import java .nio .file .Files ;
26
28
import java .util .ArrayList ;
27
- import java .util .Arrays ;
28
29
import java .util .Collections ;
29
30
import java .util .List ;
31
+ import java .util .Objects ;
30
32
import java .util .jar .JarFile ;
31
33
import java .util .jar .JarOutputStream ;
32
- import java .util .jar .Pack200 ;
33
34
import java .util .regex .Pattern ;
34
35
35
36
import com .dscalzi .zipextractor .core .ZTask ;
36
37
import com .dscalzi .zipextractor .core .managers .MessageManager ;
37
38
import com .dscalzi .zipextractor .core .util .ICommandSender ;
39
+ import com .dscalzi .zipextractor .core .util .JavaUtil ;
40
+ import com .dscalzi .zipextractor .core .util .ReflectionUtil ;
38
41
42
+ // Pack200 deprecated in JDK 13, removed in JDK 14.
43
+ // https://openjdk.java.net/jeps/367
39
44
public class PackProvider implements TypeProvider {
40
45
41
46
public static final Pattern PATH_END_EXTRACT = Pattern .compile ("\\ .pack$" );
@@ -69,7 +74,13 @@ public boolean extract(ICommandSender sender, File src, File dest, boolean log,
69
74
try (JarOutputStream jarStream = new JarOutputStream (new FileOutputStream (realDest ))) {
70
75
if (log )
71
76
mm .info ("Extracting : " + src .getAbsoluteFile ());
72
- Pack200 .newUnpacker ().unpack (src , jarStream );
77
+ try {
78
+ this .unpack (src , jarStream );
79
+ } catch (Throwable t ) {
80
+ t .printStackTrace ();
81
+ mm .genericOperationError (sender , src , ZTask .EXTRACT );
82
+ return false ;
83
+ }
73
84
if (!pipe )
74
85
mm .extractionComplete (sender , realDest );
75
86
return true ;
@@ -87,7 +98,13 @@ public boolean compress(ICommandSender sender, File src, File dest, boolean log,
87
98
try (JarFile in = new JarFile (src ); OutputStream out = Files .newOutputStream (dest .toPath ())) {
88
99
if (log )
89
100
mm .info ("Compressing : " + src .getAbsolutePath ());
90
- Pack200 .newPacker ().pack (in , out );
101
+ try {
102
+ this .pack (in , out );
103
+ } catch (Throwable t ) {
104
+ t .printStackTrace ();
105
+ mm .genericOperationError (sender , src , ZTask .COMPRESS );
106
+ return false ;
107
+ }
91
108
if (!pipe )
92
109
mm .compressionComplete (sender , dest );
93
110
return true ;
@@ -128,4 +145,60 @@ public List<String> canCompressFrom() {
128
145
return SUPPORTED_COMPRESS ;
129
146
}
130
147
148
+ @ Override
149
+ public boolean isSupported () {
150
+ return JavaUtil .getJavaVersion () < 14 ;
151
+ }
152
+
153
+ @ Override
154
+ public String getUnsupportedMessage () {
155
+ return "Pack200 support is only enabled on JDK 13 and below." ;
156
+ }
157
+
158
+ /* Access Pack200 Reflectively */
159
+
160
+ protected Class <?> getPack200Class () {
161
+ return ReflectionUtil .getClass ("java.util.jar.Pack200" );
162
+ }
163
+
164
+ protected Object getUnpacker () throws InvocationTargetException , IllegalAccessException {
165
+ Class <?> Pack200Class = this .getPack200Class ();
166
+ Method newUnpacker = Objects .requireNonNull (ReflectionUtil .getMethod (Pack200Class , "newUnpacker" ));
167
+ return newUnpacker .invoke (null );
168
+ }
169
+
170
+ protected Object getPacker () throws InvocationTargetException , IllegalAccessException {
171
+ Class <?> Pack200Class = this .getPack200Class ();
172
+ Method newPacker = Objects .requireNonNull (ReflectionUtil .getMethod (Pack200Class , "newPacker" ));
173
+ return newPacker .invoke (null );
174
+ }
175
+
176
+ protected Method getUnpackMethod () {
177
+ Class <?> Pack200Class = this .getPack200Class ();
178
+ Class <?> UnpackerClass = ReflectionUtil .getDeclaredClass (Pack200Class , "Unpacker" );
179
+ // void unpack(File in, JarOutputStream out) throws IOException;
180
+ return ReflectionUtil .getMethod (UnpackerClass , "unpack" , File .class , JarOutputStream .class );
181
+ }
182
+
183
+ protected Method getPackMethod () {
184
+ Class <?> Pack200Class = this .getPack200Class ();
185
+ Class <?> PackerClass = ReflectionUtil .getDeclaredClass (Pack200Class , "Packer" );
186
+ // void pack(JarFile in, OutputStream out) throws IOException;
187
+ return ReflectionUtil .getMethod (PackerClass , "pack" , JarFile .class , OutputStream .class );
188
+ }
189
+
190
+ protected void unpack (File in , JarOutputStream out ) throws InvocationTargetException , IllegalAccessException {
191
+ // Pack200.newUnpacker().unpack(src, jarStream);
192
+ Object unpacker = this .getUnpacker ();
193
+ Method unpackMethod = this .getUnpackMethod ();
194
+ unpackMethod .invoke (unpacker , in , out );
195
+ }
196
+
197
+ protected void pack (JarFile in , OutputStream out ) throws InvocationTargetException , IllegalAccessException {
198
+ // Pack200.newPacker().pack(in, out);
199
+ Object packer = this .getPacker ();
200
+ Method packMethod = this .getPackMethod ();
201
+ packMethod .invoke (packer , in , out );
202
+ }
203
+
131
204
}
0 commit comments