Skip to content

Commit c37c8e5

Browse files
author
Alexey Semenyuk
committed
8250950: Allow per-user and system wide configuration of a jpackaged app
Reviewed-by: almatvee
1 parent 124ba45 commit c37c8e5

File tree

15 files changed

+563
-56
lines changed

15 files changed

+563
-56
lines changed

src/jdk.jpackage/linux/native/libapplauncher/LinuxLauncherLib.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ void launchApp() {
7171
<< _T("lib/runtime"));
7272
} else {
7373
ownerPackage.initAppLauncher(appLauncher);
74+
75+
tstring homeDir;
76+
JP_TRY;
77+
homeDir = SysInfo::getEnvVariable("HOME");
78+
JP_CATCH_ALL;
79+
80+
if (!homeDir.empty()) {
81+
appLauncher.addCfgFileLookupDir(FileUtils::mkpath()
82+
<< homeDir << ".local" << ownerPackage.name());
83+
appLauncher.addCfgFileLookupDir(FileUtils::mkpath()
84+
<< homeDir << "." + ownerPackage.name());
85+
}
7486
}
7587

7688
const std::string _JPACKAGE_LAUNCHER = "_JPACKAGE_LAUNCHER";

src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java

+15-5
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
public abstract class MacBaseInstallerBundler extends AbstractBundler {
4848

49-
public final BundlerParamInfo<Path> APP_IMAGE_TEMP_ROOT =
49+
private final BundlerParamInfo<Path> APP_IMAGE_TEMP_ROOT =
5050
new StandardBundlerParam<>(
5151
"mac.app.imageRoot",
5252
Path.class,
@@ -156,15 +156,25 @@ protected void validateAppImageAndBundeler(
156156
}
157157

158158
protected Path prepareAppBundle(Map<String, ? super Object> params)
159-
throws PackagerException {
159+
throws PackagerException, IOException {
160+
Path appDir;
161+
Path appImageRoot = APP_IMAGE_TEMP_ROOT.fetchFrom(params);
160162
Path predefinedImage =
161163
StandardBundlerParam.getPredefinedAppImage(params);
162164
if (predefinedImage != null) {
163-
return predefinedImage;
165+
appDir = appImageRoot.resolve(APP_NAME.fetchFrom(params) + ".app");
166+
IOUtils.copyRecursive(predefinedImage, appDir);
167+
} else {
168+
appDir = appImageBundler.execute(params, appImageRoot);
169+
}
170+
171+
if (!StandardBundlerParam.isRuntimeInstaller(params)) {
172+
new PackageFile(APP_NAME.fetchFrom(params)).save(
173+
ApplicationLayout.macAppImage().resolveAt(appDir));
174+
Files.deleteIfExists(AppImageFile.getPathInAppImage(appDir));
164175
}
165-
Path appImageRoot = APP_IMAGE_TEMP_ROOT.fetchFrom(params);
166176

167-
return appImageBundler.execute(params, appImageRoot);
177+
return appDir;
168178
}
169179

170180
@Override

src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,8 @@ private Path buildDMG( Map<String, ? super Object> params,
277277
Path finalDMG = outdir.resolve(MAC_INSTALLER_NAME.fetchFrom(params)
278278
+ INSTALLER_SUFFIX.fetchFrom(params) + ".dmg");
279279

280-
Path srcFolder = APP_IMAGE_TEMP_ROOT.fetchFrom(params);
281-
Path predefinedImage = StandardBundlerParam.getPredefinedAppImage(params);
282-
if (predefinedImage != null) {
283-
srcFolder = predefinedImage;
284-
} else if (StandardBundlerParam.isRuntimeInstaller(params)) {
280+
Path srcFolder = appLocation.getParent();
281+
if (StandardBundlerParam.isRuntimeInstaller(params)) {
285282
Path newRoot = Files.createTempDirectory(TEMP_ROOT.fetchFrom(params),
286283
"root-");
287284

src/jdk.jpackage/macosx/native/applauncher/MacLauncher.cpp

+26-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,10 @@
2626
#include "AppLauncher.h"
2727
#include "app.h"
2828
#include "FileUtils.h"
29+
#include "PackageFile.h"
2930
#include "UnixSysInfo.h"
3031
#include "JvmLauncher.h"
32+
#include "ErrorHandling.h"
3133

3234

3335
namespace {
@@ -49,17 +51,36 @@ void initJvmLauncher() {
4951
const tstring appImageRoot = FileUtils::dirname(FileUtils::dirname(
5052
FileUtils::dirname(launcherPath)));
5153

54+
const tstring appDirPath = FileUtils::mkpath() << appImageRoot
55+
<< _T("Contents/app");
56+
57+
const PackageFile pkgFile = PackageFile::loadFromAppDir(appDirPath);
58+
5259
// Create JVM launcher and save in global variable.
53-
jvmLauncher = AppLauncher()
60+
AppLauncher appLauncher = AppLauncher()
5461
.setImageRoot(appImageRoot)
5562
.addJvmLibName(_T("Contents/Home/lib/libjli.dylib"))
5663
// add backup - older version such as JDK11 have it in jli sub-dir
5764
.addJvmLibName(_T("Contents/Home/lib/jli/libjli.dylib"))
58-
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("Contents/app"))
65+
.setAppDir(appDirPath)
5966
.setLibEnvVariableName(_T("DYLD_LIBRARY_PATH"))
6067
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
61-
<< _T("Contents/runtime"))
62-
.createJvmLauncher();
68+
<< _T("Contents/runtime"));
69+
70+
if (!pkgFile.getPackageName().empty()) {
71+
tstring homeDir;
72+
JP_TRY;
73+
homeDir = SysInfo::getEnvVariable("HOME");
74+
JP_CATCH_ALL;
75+
76+
if (!homeDir.empty()) {
77+
appLauncher.addCfgFileLookupDir(FileUtils::mkpath()
78+
<< homeDir << "Library/Application Support"
79+
<< pkgFile.getPackageName());
80+
}
81+
}
82+
83+
jvmLauncher = appLauncher.createJvmLauncher();
6384

6485
// Kick start JVM launching. The function wouldn't return!
6586
launchJvm();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package jdk.jpackage.internal;
27+
28+
import java.io.IOException;
29+
import java.nio.file.Files;
30+
import java.nio.file.Path;
31+
import java.util.Objects;
32+
import java.util.Optional;
33+
34+
public final class PackageFile {
35+
36+
/**
37+
* Returns path to package file.
38+
* @param appImageDir - path to application image
39+
*/
40+
public static Path getPathInAppImage(Path appImageDir) {
41+
return ApplicationLayout.platformAppImage()
42+
.resolveAt(appImageDir)
43+
.appDirectory()
44+
.resolve(FILENAME);
45+
}
46+
47+
PackageFile(String packageName) {
48+
Objects.requireNonNull(packageName);
49+
this.packageName = packageName;
50+
}
51+
52+
void save(ApplicationLayout appLayout) throws IOException {
53+
Path dst = Optional.ofNullable(appLayout.appDirectory()).map(appDir -> {
54+
return appDir.resolve(FILENAME);
55+
}).orElse(null);
56+
57+
if (dst != null) {
58+
Files.createDirectories(dst.getParent());
59+
Files.writeString(dst, packageName);
60+
}
61+
}
62+
63+
private final String packageName;
64+
65+
private final static String FILENAME = ".package";
66+
}

src/jdk.jpackage/share/native/applauncher/AppLauncher.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -110,9 +110,7 @@ bool AppLauncher::libEnvVariableContainsAppDir() const {
110110
}
111111

112112
Jvm* AppLauncher::createJvmLauncher() const {
113-
const tstring cfgFilePath = FileUtils::mkpath()
114-
<< appDirPath << FileUtils::stripExeSuffix(
115-
FileUtils::basename(launcherPath)) + _T(".cfg");
113+
const tstring cfgFilePath = getCfgFilePath();
116114

117115
LOG_TRACE(tstrings::any() << "Launcher config file path: \""
118116
<< cfgFilePath << "\"");
@@ -160,3 +158,20 @@ Jvm* AppLauncher::createJvmLauncher() const {
160158
void AppLauncher::launch() const {
161159
std::unique_ptr<Jvm>(createJvmLauncher())->launch();
162160
}
161+
162+
163+
tstring AppLauncher::getCfgFilePath() const {
164+
tstring_array::const_iterator it = cfgFileLookupDirs.begin();
165+
tstring_array::const_iterator end = cfgFileLookupDirs.end();
166+
const tstring cfgFileName = FileUtils::stripExeSuffix(
167+
FileUtils::basename(launcherPath)) + _T(".cfg");
168+
for (; it != end; ++it) {
169+
const tstring cfgFilePath = FileUtils::mkpath() << *it << cfgFileName;
170+
LOG_TRACE(tstrings::any() << "Check [" << cfgFilePath << "] file exit");
171+
if (FileUtils::isFileExists(cfgFilePath)) {
172+
return cfgFilePath;
173+
}
174+
}
175+
176+
return FileUtils::mkpath() << appDirPath << cfgFileName;
177+
}

src/jdk.jpackage/share/native/applauncher/AppLauncher.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,11 @@ class AppLauncher {
4545
return *this;
4646
}
4747

48+
AppLauncher& addCfgFileLookupDir(const tstring& v) {
49+
cfgFileLookupDirs.push_back(v);
50+
return *this;
51+
}
52+
4853
AppLauncher& setAppDir(const tstring& v) {
4954
appDirPath = v;
5055
return *this;
@@ -71,6 +76,9 @@ class AppLauncher {
7176

7277
void launch() const;
7378

79+
private:
80+
tstring getCfgFilePath() const;
81+
7482
private:
7583
tstring_array args;
7684
tstring launcherPath;
@@ -79,6 +87,7 @@ class AppLauncher {
7987
tstring libEnvVarName;
8088
tstring imageRoot;
8189
tstring_array jvmLibNames;
90+
tstring_array cfgFileLookupDirs;
8291
bool initJvmFromCmdlineOnly;
8392
};
8493

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
#include "kludge_c++11.h"
27+
28+
#include <fstream>
29+
#include "PackageFile.h"
30+
#include "Log.h"
31+
#include "FileUtils.h"
32+
#include "ErrorHandling.h"
33+
34+
35+
PackageFile::PackageFile(const tstring& v): packageName(v) {
36+
}
37+
38+
39+
PackageFile PackageFile::loadFromAppDir(const tstring& appDirPath) {
40+
tstring packageName;
41+
const tstring packageFilePath =
42+
FileUtils::mkpath() << appDirPath << _T(".package");
43+
if (FileUtils::isFileExists(packageFilePath)) {
44+
LOG_TRACE(tstrings::any() << "Read \"" << packageFilePath
45+
<< "\" package file");
46+
std::ifstream input(packageFilePath);
47+
if (!input.good()) {
48+
JP_THROW(tstrings::any() << "Error opening \"" << packageFilePath
49+
<< "\" file: " << lastCRTError());
50+
}
51+
52+
std::string utf8line;
53+
if (std::getline(input, utf8line)) {
54+
LOG_TRACE(tstrings::any()
55+
<< "Package name is [" << utf8line << "]");
56+
packageName = tstrings::any(utf8line).tstr();
57+
}
58+
}
59+
60+
return PackageFile(packageName);
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
27+
#ifndef PackageFile_h
28+
#define PackageFile_h
29+
30+
#include "tstrings.h"
31+
32+
33+
class PackageFile {
34+
public:
35+
static PackageFile loadFromAppDir(const tstring& appDirPath);
36+
37+
tstring getPackageName() const {
38+
return packageName;
39+
}
40+
41+
private:
42+
PackageFile(const tstring& packageName);
43+
44+
private:
45+
tstring packageName;
46+
};
47+
48+
#endif // PackageFile_h

0 commit comments

Comments
 (0)