Skip to content

Commit a8cbf02

Browse files
committed
Rewritten resolution of the starting process
- Added reporting important informations - More useful error management - --terse limits the amount of printed information - The fact that the process is alive, doesn't always mean it will be alive one second later. Check admin port too, by default. This will be configurable later. - User can configure "definition" of the started server - When process dies before the command, it is always an error - Added explicit option to print the process output - StartServerShutdownHook logging - it is kept, but the startup logging done by the AsadminMain is supported also on Windows Signed-off-by: David Matějček <[email protected]>
1 parent 5a5f734 commit a8cbf02

File tree

32 files changed

+1331
-707
lines changed

32 files changed

+1331
-707
lines changed

appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/progress/JobManagerITest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public void jobSurvivesRestart() throws Exception {
6363
"--cleanup-initial-delay=0s",
6464
"--cleanup-poll-interval=0s"), asadminOK());
6565
assertThat(ASADMIN.exec(COMMAND_PROGRESS_SIMPLE), asadminOK());
66-
assertThat(ASADMIN.exec("restart-domain", "--timeout", "60"), asadminOK());
66+
assertThat(ASADMIN.exec("restart-domain", "--timeout", "60", "domain1"), asadminOK());
6767
assertThat(ASADMIN.exec("list-jobs").getStdOut(), stringContainsInOrder(COMMAND_PROGRESS_SIMPLE, "COMPLETED"));
6868
JobTestExtension.doAndDisableJobCleanup();
6969
}

appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/rest/LoggingRestITest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import static jakarta.ws.rs.core.MediaType.TEXT_PLAIN;
3232
import static org.glassfish.main.itest.tools.GlassFishTestEnvironment.getAsadmin;
3333
import static org.glassfish.main.itest.tools.asadmin.AsadminResultMatcher.asadminOK;
34+
import static org.hamcrest.CoreMatchers.anyOf;
35+
import static org.hamcrest.CoreMatchers.startsWith;
3436
import static org.hamcrest.MatcherAssert.assertThat;
3537
import static org.hamcrest.Matchers.containsString;
3638
import static org.hamcrest.Matchers.emptyOrNullString;
@@ -39,7 +41,6 @@
3941
import static org.hamcrest.Matchers.greaterThan;
4042
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
4143
import static org.hamcrest.Matchers.not;
42-
import static org.hamcrest.Matchers.startsWith;
4344
import static org.junit.jupiter.api.Assertions.assertAll;
4445

4546
/**
@@ -55,7 +56,7 @@ public class LoggingRestITest extends RestTestBase {
5556
public static void fillUpLog() {
5657
// The server log may become empty due to log rotation.
5758
// Restart domain to fill it up.
58-
AsadminResult result = getAsadmin().exec("restart-domain", "--timeout", "60");
59+
AsadminResult result = getAsadmin().exec("restart-domain", "--timeout", "60", "domain1");
5960
assertThat(result, asadminOK());
6061
}
6162

@@ -100,7 +101,8 @@ public void logFileNames() throws Exception {
100101
// Depends on the order of tests, there may be rolled file too.
101102
assertAll(
102103
() -> assertThat("InstanceLogFileNames", logFileNames.length(), greaterThanOrEqualTo(1)),
103-
() -> assertThat(logFileNames.get(0).toString(), startsWith("server.log"))
104+
() -> assertThat(logFileNames.get(0).toString(),
105+
anyOf(startsWith("restart.log"), startsWith("server.log")))
104106
);
105107
}
106108

nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncher.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,6 @@ public String getLogFilename() {
382382
throw new IllegalStateException("Call to getLogFilename() before it has been initialized!");
383383
}
384384

385-
386385
/**
387386
* @return null or a port number
388387
*/

nucleus/admin/server-mgmt/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@
5656
<artifactId>glassfish-jdk-extensions</artifactId>
5757
<version>${project.version}</version>
5858
</dependency>
59+
<dependency>
60+
<groupId>org.glassfish.main</groupId>
61+
<artifactId>glassfish-jul-extension</artifactId>
62+
<scope>compile</scope>
63+
</dependency>
5964
<dependency>
6065
<groupId>org.glassfish.main.admin</groupId>
6166
<artifactId>admin-util</artifactId>

nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/ChangeAdminPasswordCommand.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,8 @@ private int changeAdminPasswordLocally(String domainDir, String domainName) thro
172172
throw new CommandException(strings.get("CannotExecuteLocally"));
173173
}
174174

175-
GFLauncher launcher = null;
176175
try {
177-
launcher = GFLauncherFactory.getInstance(RuntimeType.DAS);
176+
GFLauncher launcher = GFLauncherFactory.getInstance(RuntimeType.DAS);
178177
GFLauncherInfo info = launcher.getInfo();
179178
info.setDomainName(domainName);
180179
info.setDomainParentDir(domainDir);
@@ -183,31 +182,28 @@ private int changeAdminPasswordLocally(String domainDir, String domainName) thro
183182
//If secure admin is enabled and if new password is null
184183
//throw new exception
185184
if (launcher.isSecureAdminEnabled()) {
186-
if ((newpassword == null) || (newpassword.isEmpty())) {
185+
if (newpassword == null || newpassword.isEmpty()) {
187186
throw new CommandException(strings.get("NullNewPassword"));
188187
}
189188
}
190189

191190
String adminKeyFile = launcher.getAdminRealmKeyFile();
192191

193-
if (adminKeyFile != null) {
194-
//This is a FileRealm, instantiate it.
195-
FileRealmHelper helper = new FileRealmHelper(adminKeyFile);
196-
197-
//Authenticate the old password
198-
String[] groups = helper.authenticate(programOpts.getUser(), password.toCharArray());
199-
if (groups == null) {
200-
throw new CommandException(strings.get("InvalidCredentials", programOpts.getUser()));
201-
}
202-
helper.updateUser(programOpts.getUser(), programOpts.getUser(), newpassword.toCharArray(), null);
203-
helper.persist();
204-
return SUCCESS;
205-
206-
} else {
192+
if (adminKeyFile == null) {
207193
//Cannot change password locally for non file realms
208194
throw new CommandException(strings.get("NotFileRealmCannotChangeLocally"));
195+
}
196+
//This is a FileRealm, instantiate it.
197+
FileRealmHelper helper = new FileRealmHelper(adminKeyFile);
209198

199+
//Authenticate the old password
200+
String[] groups = helper.authenticate(programOpts.getUser(), password.toCharArray());
201+
if (groups == null) {
202+
throw new CommandException(strings.get("InvalidCredentials", programOpts.getUser()));
210203
}
204+
helper.updateUser(programOpts.getUser(), programOpts.getUser(), newpassword.toCharArray(), null);
205+
helper.persist();
206+
return SUCCESS;
211207

212208
} catch (MiniXmlParserException ex) {
213209
throw new CommandException(ex);

nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/ChangeMasterPasswordCommand.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Copyright (c) 2025 Contributors to the Eclipse Foundation.
23
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
34
*
45
* This program and the accompanying materials are made available under the
@@ -92,21 +93,19 @@ protected int executeCommand() throws CommandException {
9293
if (nodeDir != null) {
9394
command = CLICommand.getCommand(habitat, CHANGE_MASTER_PASSWORD_NODE);
9495
return command.execute(argv);
95-
} else {
96-
97-
// nodeDir is not specified and domainNameOrNodeName is not a domain.
98-
// It could be a node
99-
// We add defaultNodeDir parameter to args
100-
ArrayList arguments = new ArrayList<String>(Arrays.asList(argv));
101-
arguments.remove(argv.length - 1);
102-
arguments.add("--nodedir");
103-
arguments.add(getDefaultNodesDirs().getAbsolutePath());
104-
arguments.add(domainNameOrNodeName);
105-
String[] newargs = (String[]) arguments.toArray(new String[arguments.size()]);
106-
107-
command = CLICommand.getCommand(habitat, CHANGE_MASTER_PASSWORD_NODE);
108-
return command.execute(newargs);
10996
}
97+
// nodeDir is not specified and domainNameOrNodeName is not a domain.
98+
// It could be a node
99+
// We add defaultNodeDir parameter to args
100+
ArrayList<String> arguments = new ArrayList<>(Arrays.asList(argv));
101+
arguments.remove(argv.length - 1);
102+
arguments.add("--nodedir");
103+
arguments.add(getDefaultNodesDirs().getAbsolutePath());
104+
arguments.add(domainNameOrNodeName);
105+
String[] newargs = arguments.toArray(String[]::new);
106+
107+
command = CLICommand.getCommand(habitat, CHANGE_MASTER_PASSWORD_NODE);
108+
return command.execute(newargs);
110109
} catch (IOException e) {
111110
throw new CommandException(e.getMessage(), e);
112111
}

nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/ChangeMasterPasswordCommandDAS.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation
33
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
44
*
55
* This program and the accompanying materials are made available under the
@@ -19,7 +19,6 @@
1919

2020
import com.sun.enterprise.admin.servermgmt.DomainConfig;
2121
import com.sun.enterprise.admin.servermgmt.pe.PEDomainsManager;
22-
import com.sun.enterprise.universal.process.ProcessUtils;
2322
import com.sun.enterprise.util.HostAndPort;
2423

2524
import org.glassfish.api.Param;
@@ -68,10 +67,7 @@ public int execute(String... argv) throws CommandException {
6867
protected int executeCommand() throws CommandException {
6968

7069
try {
71-
HostAndPort adminAddress = getAdminAddress();
72-
if (ProcessUtils.isListening(adminAddress)) {
73-
throw new CommandException(strings.get("domain.is.running", getDomainName(), getDomainRootDir()));
74-
}
70+
checkServerIsNotRunning();
7571
DomainConfig domainConfig = new DomainConfig(getDomainName(), getDomainsDir().getAbsolutePath());
7672
PEDomainsManager manager = new PEDomainsManager();
7773
String mp = super.readFromMasterPasswordFile();
@@ -106,4 +102,12 @@ protected int executeCommand() throws CommandException {
106102
throw new CommandException(e.getMessage(), e);
107103
}
108104
}
105+
106+
private void checkServerIsNotRunning() throws CommandException {
107+
HostAndPort adminAddress = getReachableAdminAddress(getDomainXml());
108+
if (adminAddress == null) {
109+
return;
110+
}
111+
throw new CommandException(strings.get("domain.is.running", getDomainName(), getDomainRootDir()));
112+
}
109113
}

nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/DeleteDomainCommand.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation
33
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
44
*
55
* This program and the accompanying materials are made available under the
@@ -20,7 +20,6 @@
2020
import com.sun.enterprise.admin.servermgmt.DomainConfig;
2121
import com.sun.enterprise.admin.servermgmt.DomainsManager;
2222
import com.sun.enterprise.admin.servermgmt.pe.PEDomainsManager;
23-
import com.sun.enterprise.universal.process.ProcessUtils;
2423
import com.sun.enterprise.util.HostAndPort;
2524

2625
import java.io.File;
@@ -54,7 +53,7 @@ public final class DeleteDomainCommand extends LocalDomainCommand {
5453
protected void validate() throws CommandException, CommandValidationException {
5554
setDomainName(domainName0);
5655
super.validate();
57-
adminAddress = super.getAdminAddress();
56+
adminAddress = getReachableAdminAddress(getDomainXml());
5857
}
5958

6059
/**
@@ -79,9 +78,10 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti
7978
return 0;
8079
}
8180

82-
private void checkRunning() throws CommandException {
83-
programOpts.setInteractive(false); // don't prompt for password
84-
if (isThisDAS(getDomainRootDir()) && ProcessUtils.isListening(adminAddress)) {
81+
private void checkRunning() {
82+
// don't prompt for password
83+
programOpts.setInteractive(false);
84+
if (isThisDAS(getDomainRootDir()) && adminAddress != null) {
8585
String msg = strings.get("domain.is.running", getDomainName(), getDomainRootDir());
8686
throw new IllegalStateException(msg);
8787
}
@@ -90,7 +90,7 @@ private void checkRunning() throws CommandException {
9090
/**
9191
* Check that the domain directory can be renamed, to increase the likelyhood that it can be deleted.
9292
*/
93-
private void checkRename() throws CommandException {
93+
private void checkRename() {
9494
boolean ok = true;
9595
try {
9696
File root = getDomainsDir();

nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/ListDomainsCommand.java

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation
33
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
44
*
55
* This program and the accompanying materials are made available under the
@@ -26,7 +26,8 @@
2626
import com.sun.enterprise.util.io.DomainDirs;
2727

2828
import java.io.File;
29-
import java.io.IOException;
29+
import java.util.List;
30+
import java.util.logging.Level;
3031

3132
import org.glassfish.api.Param;
3233
import org.glassfish.api.admin.CommandException;
@@ -68,11 +69,11 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti
6869
programOpts.setInteractive(false); // no prompting for passwords
6970
if (domainsList.length > 0) {
7071
if (longOpt) {
71-
String headings[] = { "DOMAIN", "ADMIN_HOST", "ADMIN_PORT", "RUNNING", "RESTART_REQUIRED" };
72+
String headings[] = { "DOMAIN", "ADMIN_ENDPOINTS", "RUNNING", "RESTART_REQUIRED" };
7273
ColumnFormatter cf = header ? new ColumnFormatter(headings) : new ColumnFormatter();
7374
for (String dn : domainsList) {
7475
DomainInfo di = getStatus(dn);
75-
cf.addRow(new Object[] { dn, di.adminAddr.getHost(), di.adminAddr.getPort(), di.status, di.restartRequired });
76+
cf.addRow(new Object[] { dn, di.getAdminEndpoints(), di.status, di.restartRequired });
7677
}
7778
logger.info(cf.toString());
7879
} else {
@@ -83,41 +84,49 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti
8384
} else {
8485
logger.fine(strings.get("NoDomainsToList"));
8586
}
86-
} catch (Exception ex) {
87-
throw new CommandException(ex.getLocalizedMessage());
87+
} catch (Exception e) {
88+
throw new CommandException(e.getLocalizedMessage(), e);
8889
}
8990
return 0;
9091
}
9192

92-
static class DomainInfo {
93-
public HostAndPort adminAddr;
94-
public boolean status;
95-
public String statusMsg;
96-
public boolean restartRequired;
97-
}
98-
99-
private DomainInfo getStatus(String dn) throws IOException, CommandException {
100-
setDomainName(dn);
93+
private DomainInfo getStatus(String domainName) throws CommandException {
94+
// We have to change these to get the right domain.xml
95+
setDomainName(domainName);
10196
initDomain();
102-
DomainInfo di = new DomainInfo();
103-
di.adminAddr = getAdminAddress("server");
104-
programOpts.setHostAndPort(di.adminAddr);
105-
di.status = isThisDAS(getDomainRootDir());
106-
107-
if (di.status) {
108-
di.statusMsg = strings.get("list.domains.StatusRunning", dn);
97+
DomainInfo info = new DomainInfo();
98+
info.adminAddr = getAdminAddresses(getDomainXml(), "server");
99+
HostAndPort reachableEndpoint = getReachableAdminAddress(getDomainXml());
100+
if (reachableEndpoint == null) {
101+
info.status = false;
102+
info.statusMsg = strings.get("list.domains.StatusNotRunning", domainName);
103+
} else {
104+
programOpts.setHostAndPort(reachableEndpoint);
105+
info.status = isThisDAS(getDomainRootDir());
106+
info.statusMsg = strings.get("list.domains.StatusRunning", domainName);
109107
try {
110108
RemoteCLICommand cmd = new RemoteCLICommand("_get-restart-required", programOpts, env);
111109
String restartRequired = cmd.executeAndReturnOutput("_get-restart-required");
112-
di.restartRequired = Boolean.parseBoolean(restartRequired.trim());
113-
if (di.restartRequired) {
114-
di.statusMsg = strings.get("list.domains.StatusRestartRequired", dn);
110+
info.restartRequired = Boolean.parseBoolean(restartRequired.trim());
111+
if (info.restartRequired) {
112+
info.statusMsg = strings.get("list.domains.StatusRestartRequired", domainName);
115113
}
116-
} catch (Exception ex) {
114+
} catch (Exception e) {
115+
logger.log(Level.WARNING, "Failed to check domain status for " + domainName, e);
117116
}
118-
} else {
119-
di.statusMsg = strings.get("list.domains.StatusNotRunning", dn);
120117
}
121-
return di;
118+
return info;
119+
}
120+
121+
122+
private static class DomainInfo {
123+
List<HostAndPort> adminAddr;
124+
boolean status;
125+
String statusMsg;
126+
boolean restartRequired;
127+
128+
private String getAdminEndpoints() {
129+
return StartServerHelper.toHttpList(adminAddr);
130+
}
122131
}
123132
}

nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/LocalDomainCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public abstract class LocalDomainCommand extends LocalServerCommand {
4242
// the key for the Domain Root in the main attributes of the
4343
// manifest returned by the __locations command
4444
private static final String DOMAIN_ROOT_KEY = "Domain-Root";
45-
private DomainDirs dd = null;
45+
private DomainDirs dd;
4646

4747
/*
4848
* The prepare method must ensure that the superclass' implementation of

0 commit comments

Comments
 (0)