35 import jdk.jpackage.test.Functional.ThrowingFunction; |
35 import jdk.jpackage.test.Functional.ThrowingFunction; |
36 import jdk.jpackage.test.Functional.ThrowingSupplier; |
36 import jdk.jpackage.test.Functional.ThrowingSupplier; |
37 |
37 |
38 public class HelloApp { |
38 public class HelloApp { |
39 |
39 |
40 private HelloApp() { |
40 HelloApp(JavaAppDesc appDesc) { |
41 setClassName(CLASS_NAME).setJarFileName("hello.jar"); |
41 if (appDesc == null) { |
42 } |
42 this.appDesc = createDefaltAppDesc(); |
43 |
43 } else { |
44 /** |
44 this.appDesc = appDesc; |
45 * Set fully qualified class name. E.g: foo.bar.Buzz. |
45 } |
46 */ |
|
47 private HelloApp setClassName(String v) { |
|
48 qualifiedClassName = v; |
|
49 return this; |
|
50 } |
|
51 |
|
52 private HelloApp setModuleName(String v) { |
|
53 moduleName = v; |
|
54 return this; |
|
55 } |
|
56 |
|
57 private HelloApp setJarFileName(String v) { |
|
58 jarFileName = v; |
|
59 return this; |
|
60 } |
|
61 |
|
62 private HelloApp setModuleVersion(String v) { |
|
63 moduleVersion = v; |
|
64 return this; |
|
65 } |
46 } |
66 |
47 |
67 private JarBuilder prepareSources(Path srcDir) throws IOException { |
48 private JarBuilder prepareSources(Path srcDir) throws IOException { |
|
49 final String qualifiedClassName = appDesc.className(); |
|
50 |
68 final String className = qualifiedClassName.substring( |
51 final String className = qualifiedClassName.substring( |
69 qualifiedClassName.lastIndexOf('.') + 1); |
52 qualifiedClassName.lastIndexOf('.') + 1); |
70 final String packageName = packageName(); |
53 final String packageName = appDesc.packageName(); |
71 |
54 |
72 final Path srcFile = srcDir.resolve(Path.of(String.join( |
55 final Path srcFile = srcDir.resolve(Path.of(String.join( |
73 File.separator, qualifiedClassName.split("\\.")) + ".java")); |
56 File.separator, qualifiedClassName.split("\\.")) + ".java")); |
74 Files.createDirectories(srcFile.getParent()); |
57 Files.createDirectories(srcFile.getParent()); |
75 |
58 |
76 JarBuilder jarBuilder = createJarBuilder().addSourceFile(srcFile); |
59 JarBuilder jarBuilder = createJarBuilder().addSourceFile(srcFile); |
|
60 final String moduleName = appDesc.moduleName(); |
77 if (moduleName != null) { |
61 if (moduleName != null) { |
78 Path moduleInfoFile = srcDir.resolve("module-info.java"); |
62 Path moduleInfoFile = srcDir.resolve("module-info.java"); |
79 TKit.createTextFile(moduleInfoFile, List.of( |
63 TKit.createTextFile(moduleInfoFile, List.of( |
80 String.format("module %s {", moduleName), |
64 String.format("module %s {", moduleName), |
81 String.format(" exports %s;", packageName), |
65 String.format(" exports %s;", packageName), |
82 "}" |
66 "}" |
83 )); |
67 )); |
84 jarBuilder.addSourceFile(moduleInfoFile); |
68 jarBuilder.addSourceFile(moduleInfoFile); |
85 if (moduleVersion != null) { |
69 jarBuilder.setModuleVersion(appDesc.moduleVersion()); |
86 jarBuilder.setModuleVersion(moduleVersion); |
|
87 } |
|
88 } |
70 } |
89 |
71 |
90 // Add package directive and replace class name in java source file. |
72 // Add package directive and replace class name in java source file. |
91 // Works with simple test Hello.java. |
73 // Works with simple test Hello.java. |
92 // Don't expect too much from these regexps! |
74 // Don't expect too much from these regexps! |
122 |
104 |
123 return jarBuilder; |
105 return jarBuilder; |
124 } |
106 } |
125 |
107 |
126 private JarBuilder createJarBuilder() { |
108 private JarBuilder createJarBuilder() { |
127 return new JarBuilder().setMainClass(qualifiedClassName); |
109 JarBuilder builder = new JarBuilder(); |
128 } |
110 if (appDesc.jarWithMainClass()) { |
129 |
111 builder.setMainClass(appDesc.className()); |
130 private void addTo(JPackageCommand cmd) { |
112 } |
131 if (moduleName != null && packageName() == null) { |
113 return builder; |
|
114 } |
|
115 |
|
116 void addTo(JPackageCommand cmd) { |
|
117 final String moduleName = appDesc.moduleName(); |
|
118 final String jarFileName = appDesc.jarFileName(); |
|
119 final String qualifiedClassName = appDesc.className(); |
|
120 |
|
121 if (moduleName != null && appDesc.packageName() == null) { |
132 throw new IllegalArgumentException(String.format( |
122 throw new IllegalArgumentException(String.format( |
133 "Module [%s] with default package", moduleName)); |
123 "Module [%s] with default package", moduleName)); |
134 } |
124 } |
135 |
125 |
136 if (moduleName == null && CLASS_NAME.equals(qualifiedClassName)) { |
126 if (moduleName == null && CLASS_NAME.equals(qualifiedClassName)) { |
175 if (TKit.isWindows()) { |
165 if (TKit.isWindows()) { |
176 cmd.addArguments("--win-console"); |
166 cmd.addArguments("--win-console"); |
177 } |
167 } |
178 } |
168 } |
179 |
169 |
180 private String packageName() { |
170 static JavaAppDesc createDefaltAppDesc() { |
181 int lastDotIdx = qualifiedClassName.lastIndexOf('.'); |
171 return new JavaAppDesc().setClassName(CLASS_NAME).setJarFileName( |
182 if (lastDotIdx == -1) { |
172 "hello.jar"); |
183 return null; |
|
184 } |
|
185 return qualifiedClassName.substring(0, lastDotIdx); |
|
186 } |
|
187 |
|
188 /** |
|
189 * Configures Java application to be used with the given jpackage command. |
|
190 * Syntax of encoded Java application description is |
|
191 * [jar_file:][module_name/]qualified_class_name[@module_version]. |
|
192 * |
|
193 * E.g.: duke.jar:com.other/com.other.foo.bar.Buz@3.7 encodes modular |
|
194 * application. Module name is `com.other`. Main class is |
|
195 * `com.other.foo.bar.Buz`. Module version is `3.7`. Application will be |
|
196 * compiled and packed in `duke.jar` jar file. |
|
197 * |
|
198 * @param cmd jpackage command to configure |
|
199 * @param javaAppDesc encoded Java application description |
|
200 */ |
|
201 static void addTo(JPackageCommand cmd, String javaAppDesc) { |
|
202 HelloApp helloApp = new HelloApp(); |
|
203 if (javaAppDesc != null) { |
|
204 String moduleNameAndOther = Functional.identity(() -> { |
|
205 String[] components = javaAppDesc.split(":", 2); |
|
206 if (components.length == 2) { |
|
207 helloApp.setJarFileName(components[0]); |
|
208 } |
|
209 return components[components.length - 1]; |
|
210 }).get(); |
|
211 |
|
212 String classNameAndOther = Functional.identity(() -> { |
|
213 String[] components = moduleNameAndOther.split("/", 2); |
|
214 if (components.length == 2) { |
|
215 helloApp.setModuleName(components[0]); |
|
216 } |
|
217 return components[components.length - 1]; |
|
218 }).get(); |
|
219 |
|
220 Functional.identity(() -> { |
|
221 String[] components = classNameAndOther.split("@", 2); |
|
222 helloApp.setClassName(components[0]); |
|
223 if (components.length == 2) { |
|
224 helloApp.setModuleVersion(components[1]); |
|
225 } |
|
226 }).run(); |
|
227 } |
|
228 helloApp.addTo(cmd); |
|
229 } |
173 } |
230 |
174 |
231 static void verifyOutputFile(Path outputFile, List<String> args) { |
175 static void verifyOutputFile(Path outputFile, List<String> args) { |
232 if (!outputFile.isAbsolute()) { |
176 if (!outputFile.isAbsolute()) { |
233 verifyOutputFile(outputFile.toAbsolutePath().normalize(), args); |
177 verifyOutputFile(outputFile.toAbsolutePath().normalize(), args); |
248 TKit.assertStringListEquals(expected, contents, String.format( |
192 TKit.assertStringListEquals(expected, contents, String.format( |
249 "Check contents of [%s] file", outputFile)); |
193 "Check contents of [%s] file", outputFile)); |
250 } |
194 } |
251 |
195 |
252 public static void executeLauncherAndVerifyOutput(JPackageCommand cmd) { |
196 public static void executeLauncherAndVerifyOutput(JPackageCommand cmd) { |
253 final Path launcherPath; |
197 final Path launcherPath = cmd.appLauncherPath(); |
254 if (cmd.packageType() == PackageType.IMAGE) { |
198 if (!cmd.isFakeRuntime(String.format("Not running [%s] launcher", |
255 launcherPath = cmd.appImage().resolve(cmd.launcherPathInAppImage()); |
199 launcherPath))) { |
256 if (cmd.isFakeRuntimeInAppImage(String.format( |
200 executeAndVerifyOutput(launcherPath, cmd.getAllArgumentValues( |
257 "Not running [%s] launcher from application image", |
201 "--arguments")); |
258 launcherPath))) { |
202 } |
259 return; |
|
260 } |
|
261 } else { |
|
262 launcherPath = cmd.launcherInstallationPath(); |
|
263 if (cmd.isFakeRuntimeInstalled(String.format( |
|
264 "Not running [%s] launcher", launcherPath))) { |
|
265 return; |
|
266 } |
|
267 } |
|
268 |
|
269 executeAndVerifyOutput(launcherPath, cmd.getAllArgumentValues( |
|
270 "--arguments")); |
|
271 } |
203 } |
272 |
204 |
273 public static void executeAndVerifyOutput(Path helloAppLauncher, |
205 public static void executeAndVerifyOutput(Path helloAppLauncher, |
274 String... defaultLauncherArgs) { |
206 String... defaultLauncherArgs) { |
275 executeAndVerifyOutput(helloAppLauncher, List.of(defaultLauncherArgs)); |
207 executeAndVerifyOutput(helloAppLauncher, List.of(defaultLauncherArgs)); |
276 } |
208 } |
277 |
209 |
278 public static void executeAndVerifyOutput(Path helloAppLauncher, |
210 public static void executeAndVerifyOutput(Path helloAppLauncher, |
279 List<String> defaultLauncherArgs) { |
211 List<String> defaultLauncherArgs) { |
280 // Output file will be created in the current directory. |
212 // Output file will be created in the current directory. |
281 Path outputFile = Path.of(OUTPUT_FILENAME); |
213 Path outputFile = TKit.workDir().resolve(OUTPUT_FILENAME); |
282 ThrowingFunction.toFunction(Files::deleteIfExists).apply(outputFile); |
214 ThrowingFunction.toFunction(Files::deleteIfExists).apply(outputFile); |
283 new Executor() |
215 new Executor() |
284 .setDirectory(outputFile.getParent()) |
216 .setDirectory(outputFile.getParent()) |
285 .setExecutable(helloAppLauncher) |
217 .setExecutable(helloAppLauncher) |
286 .execute() |
218 .execute() |
289 verifyOutputFile(outputFile, defaultLauncherArgs); |
221 verifyOutputFile(outputFile, defaultLauncherArgs); |
290 } |
222 } |
291 |
223 |
292 final static String OUTPUT_FILENAME = "appOutput.txt"; |
224 final static String OUTPUT_FILENAME = "appOutput.txt"; |
293 |
225 |
294 private String qualifiedClassName; |
226 private final JavaAppDesc appDesc; |
295 private String moduleName; |
|
296 private String jarFileName; |
|
297 private String moduleVersion; |
|
298 |
227 |
299 private static final Path HELLO_JAVA = TKit.TEST_SRC_ROOT.resolve( |
228 private static final Path HELLO_JAVA = TKit.TEST_SRC_ROOT.resolve( |
300 "apps/image/Hello.java"); |
229 "apps/image/Hello.java"); |
301 |
230 |
302 private final static String CLASS_NAME = HELLO_JAVA.getFileName().toString().split( |
231 private final static String CLASS_NAME = HELLO_JAVA.getFileName().toString().split( |