Skip to content

Commit 342086c

Browse files
authored
Merge pull request #25790 from dmatej/restarts
More flexibility to control server start
2 parents af91427 + 01101fb commit 342086c

File tree

39 files changed

+1586
-766
lines changed

39 files changed

+1586
-766
lines changed

appserver/itest-tools/src/main/java/org/glassfish/main/itest/tools/asadmin/Asadmin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ private File getPasswordFile() {
242242
*/
243243
private AsadminResult exec(final Integer timeout, final boolean detachedAndTerse, final String... args) {
244244
final List<String> parameters = Arrays.asList(args);
245-
LOG.log(TRACE, "exec(timeout={0}, detached={1}, args={2})", timeout, detachedAndTerse, parameters);
245+
LOG.log(INFO, "exec(timeout={0}, detached={1}, args={2})", timeout, detachedAndTerse, parameters);
246246
final List<String> command = new ArrayList<>();
247247
if (asadmin.getName().endsWith(".java")) {
248248
command.add(JAVA_EXECUTABLE);

appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBHelper.java

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,28 @@
1717

1818
package org.glassfish.enterprise.iiop.api;
1919

20-
import com.sun.logging.LogDomains;
21-
2220
import jakarta.annotation.PostConstruct;
23-
import jakarta.annotation.PreDestroy;
2421
import jakarta.ejb.Singleton;
2522
import jakarta.inject.Inject;
2623
import jakarta.inject.Provider;
2724

25+
import java.lang.System.Logger;
2826
import java.nio.channels.SelectableChannel;
2927
import java.rmi.Remote;
3028
import java.util.Properties;
31-
import java.util.logging.Level;
32-
import java.util.logging.Logger;
3329

3430
import org.glassfish.api.admin.ProcessEnvironment;
31+
import org.glassfish.api.event.EventListener;
32+
import org.glassfish.api.event.Events;
3533
import org.glassfish.api.naming.GlassfishNamingManager;
3634
import org.glassfish.hk2.api.ServiceLocator;
3735
import org.glassfish.internal.api.ORBLocator;
3836
import org.jvnet.hk2.annotations.Service;
3937
import org.omg.CORBA.ORB;
4038
import org.omg.PortableInterceptor.ServerRequestInfo;
4139

42-
import static com.sun.logging.LogDomains.CORBA_LOGGER;
40+
import static java.lang.System.Logger.Level.INFO;
41+
import static org.glassfish.api.event.EventTypes.SERVER_SHUTDOWN;
4342

4443
/**
4544
* This class exposes any orb/iiop functionality needed by modules in the app server.
@@ -51,7 +50,10 @@
5150
@Singleton
5251
public class GlassFishORBHelper implements ORBLocator {
5352

54-
private static final Logger LOG = LogDomains.getLogger(GlassFishORBHelper.class, CORBA_LOGGER, false);
53+
private static final Logger LOG = System.getLogger(GlassFishORBHelper.class.getName());
54+
55+
@Inject
56+
private Provider<Events> eventsProvider;
5557

5658
@Inject
5759
private ServiceLocator services;
@@ -75,17 +77,35 @@ public class GlassFishORBHelper implements ORBLocator {
7577

7678
@PostConstruct
7779
public void postConstruct() {
80+
// WARN: Neither PreDestroy annotation nor interface worked!
81+
EventListener glassfishEventListener = event -> {
82+
if (event.is(SERVER_SHUTDOWN)) {
83+
onShutdown();
84+
}
85+
};
86+
eventsProvider.get().register(glassfishEventListener);
7887
orbFactory = services.getService(GlassFishORBFactory.class);
88+
LOG.log(INFO, "GlassFishORBLocator created.");
7989
}
8090

81-
@PreDestroy
82-
public void onShutdown() {
91+
private void onShutdown() {
8392
// FIXME: getORB is able to create another, it should be refactored and simplified.
8493
destroyed = true;
85-
LOG.log(Level.CONFIG, "ORB Shutdown started");
86-
if (orb != null) {
87-
orb.destroy();
94+
LOG.log(INFO, "ORB shutdown started");
95+
if (this.orb != null) {
96+
// First remove, then destroy.
97+
// Still, threads already working with the instance will have it unstable.
98+
final ORB destroyedOrb = orb;
8899
orb = null;
100+
// FIXME: com.sun.corba.ee.impl.transport.AcceptorImpl.getAcceptedSocket(AcceptorImpl.java:127)
101+
// can still be blocked in standalone thread, that would lead to its failure
102+
// and cascade leading sockets open. Restart of the server could fail then.
103+
try {
104+
Thread.sleep(1000L);
105+
} catch (InterruptedException e) {
106+
// We don't want to interrupt here.
107+
}
108+
destroyedOrb.destroy();
89109
}
90110
}
91111

appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPSSLSocketFactory.java

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232
import java.net.SocketException;
3333
import java.nio.channels.ServerSocketChannel;
3434
import java.nio.channels.SocketChannel;
35+
import java.time.Duration;
36+
import java.time.Instant;
3537
import java.util.ArrayList;
38+
import java.util.Arrays;
3639
import java.util.Hashtable;
3740
import java.util.List;
3841
import java.util.Map;
@@ -89,7 +92,7 @@ public class IIOPSSLSocketFactory implements ORBSocketFactory {
8992
* @todo provide an interface to the admin, so that whenever a iiop-listener
9093
* is added / removed, we modify the hashtable,
9194
*/
92-
private final Map portToSSLInfo = new Hashtable();
95+
private final Map<Integer, SSLInfo> portToSSLInfo = new Hashtable<>();
9396
/* this is stored for the client side of SSL Connections.
9497
* Note: There will be only 1 ctx for the client side, as we will reuse the
9598
* ctx for all SSL connections
@@ -175,8 +178,7 @@ public IIOPSSLSocketFactory() {
175178
}
176179
}
177180
} catch (Exception e) {
178-
LOG.log(Level.SEVERE,"IIOPSSLSocketFactory initialization failed.", e);
179-
throw new IllegalStateException(e);
181+
throw new IllegalStateException("IIOPSSLSocketFactory initialization failed.", e);
180182
}
181183
}
182184

@@ -251,25 +253,23 @@ public void setORB(ORB orb) {
251253
*/
252254
@Override
253255
public ServerSocket createServerSocket(String type, InetSocketAddress inetSocketAddress) throws IOException {
254-
if (LOG.isLoggable(Level.FINE)) {
255-
LOG.log(Level.FINE, "Creating server socket for type =" + type
256-
+ " inetSocketAddress =" + inetSocketAddress);
257-
}
256+
LOG.log(Level.INFO, "Creating server socket for type =" + type + " inetSocketAddress =" + inetSocketAddress);
258257

259-
if(type.equals(SSL_MUTUALAUTH) || type.equals(SSL) ||
260-
type.equals(PERSISTENT_SSL)) {
258+
if (type.equals(SSL_MUTUALAUTH) || type.equals(SSL) || type.equals(PERSISTENT_SSL)) {
261259
return createSSLServerSocket(type, inetSocketAddress);
262260
}
263-
ServerSocket serverSocket = null;
261+
final ServerSocket serverSocket;
264262
if (orb.getORBData().acceptorSocketType().equals(SOCKETCHANNEL)) {
265263
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
266264
serverSocket = serverSocketChannel.socket();
267265
} else {
268266
serverSocket = new ServerSocket();
269267
}
270-
271-
serverSocket.bind(inetSocketAddress);
272-
return serverSocket;
268+
final Action<ServerSocket> action = () -> {
269+
serverSocket.bind(inetSocketAddress);
270+
return serverSocket;
271+
};
272+
return repeat(action, Duration.ofSeconds(10L));
273273
}
274274

275275
/**
@@ -339,7 +339,7 @@ private ServerSocket createSSLServerSocket(String type, InetSocketAddress inetSo
339339
}
340340
int port = inetSocketAddress.getPort();
341341
Integer iport = Integer.valueOf(port);
342-
SSLInfo sslInfo = (SSLInfo)portToSSLInfo.get(iport);
342+
SSLInfo sslInfo = portToSSLInfo.get(iport);
343343
if (sslInfo == null) {
344344
throw new IOException("No SSL info found for port " + iport);
345345
}
@@ -351,42 +351,21 @@ private ServerSocket createSSLServerSocket(String type, InetSocketAddress inetSo
351351
String[] socketCiphers = ssf.getDefaultCipherSuites();
352352
ciphers = mergeCiphers(socketCiphers, ssl3TlsCiphers, ssl2Ciphers);
353353
}
354-
355-
String cs[] = null;
356-
357-
if (LOG.isLoggable(Level.FINE)) {
358-
cs = ssf.getSupportedCipherSuites();
359-
for (String element : cs) {
360-
LOG.log(Level.FINE, "Cipher Suite: " + element);
361-
}
354+
LOG.log(Level.FINE, () -> "Supported cipher Suites: " + Arrays.toString(ssf.getSupportedCipherSuites()));
355+
final Action<ServerSocket> action = () -> ssf.createServerSocket(port, BACKLOG, inetSocketAddress.getAddress());
356+
final ServerSocket ss = repeat(action, Duration.ofSeconds(10L));
357+
if (ciphers != null) {
358+
((SSLServerSocket) ss).setEnabledCipherSuites(ciphers);
362359
}
363-
ServerSocket ss = null;
364-
try {
365-
// bugfix for 6349541
366-
// specify the ip address to bind to, 50 is the default used
367-
// by the ssf implementation when only the port is specified
368-
ss = ssf.createServerSocket(port, BACKLOG, inetSocketAddress.getAddress());
369-
if (ciphers != null) {
370-
((SSLServerSocket) ss).setEnabledCipherSuites(ciphers);
371-
}
372-
} catch (IOException e) {
373-
LOG.log(Level.SEVERE, "createServerSocket failed", new Object[] {type, port});
374-
LOG.log(Level.SEVERE, "", e);
375-
throw e;
376-
}
377-
378360
try {
379361
if (type.equals(SSL_MUTUALAUTH)) {
380362
LOG.log(Level.FINE, "Setting Mutual auth");
381363
((SSLServerSocket) ss).setNeedClientAuth(true);
382364
}
383365
} catch (Exception e) {
384-
LOG.log(Level.SEVERE, "Setting Mutual auth failed.", e);
385-
throw new IOException(e.getMessage());
386-
}
387-
if (LOG.isLoggable(Level.FINE)) {
388-
LOG.log(Level.FINE, "Created server socket:" + ss);
366+
throw new IOException(e.getMessage(), e);
389367
}
368+
LOG.log(Level.FINE, () -> "Created server socket: " + ss);
390369
return ss;
391370
}
392371

@@ -424,9 +403,7 @@ private Socket createSSLSocket(String host, int port) throws IOException {
424403
LOG.log(Level.FINE, "createSSLSocket failed.", new Object[] {host, port});
425404
LOG.log(Level.FINE, "", e);
426405
}
427-
IOException e2 = new IOException("Error opening SSL socket to host=" + host + " port=" + port);
428-
e2.initCause(e);
429-
throw e2;
406+
throw new IOException("Error opening SSL socket to host=" + host + " port=" + port, e);
430407
}
431408
return socket;
432409
}
@@ -550,6 +527,20 @@ private boolean isValidProtocolCipher(CipherInfo cipherInfo,
550527
}
551528

552529

530+
private static <T> T repeat(Action<T> action, Duration timeout) throws IOException {
531+
final Instant deadline = Instant.now().plus(timeout);
532+
while (true) {
533+
try {
534+
return action.get();
535+
} catch (Exception e) {
536+
if (Instant.now().isAfter(deadline)) {
537+
throw e;
538+
}
539+
}
540+
}
541+
}
542+
543+
553544
class SSLInfo {
554545
private final SSLContext ctx;
555546
private String[] ssl3TlsCiphers = null;
@@ -573,4 +564,9 @@ String[] getSsl2Ciphers() {
573564
return ssl2Ciphers;
574565
}
575566
}
567+
568+
@FunctionalInterface
569+
private interface Action<T> {
570+
T get() throws IOException;
571+
}
576572
}

appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/AsadminLoggingITest.java

Lines changed: 12 additions & 5 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
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,6 +16,8 @@
1616

1717
package org.glassfish.main.admin.test;
1818

19+
import com.sun.enterprise.util.OS;
20+
1921
import java.io.File;
2022
import java.io.FileReader;
2123
import java.io.LineNumberReader;
@@ -69,11 +71,16 @@ public class AsadminLoggingITest {
6971

7072
private static final Asadmin ASADMIN = GlassFishTestEnvironment.getAsadmin();
7173

74+
/** Fill up the server log. */
7275
@BeforeAll
73-
public static void fillUpServerLog() {
74-
// Fill up the server log.
75-
AsadminResult result = ASADMIN.exec("restart-domain", "--timeout", "60");
76-
assertThat(result, asadminOK());
76+
public static void fillUpServerLog() throws Exception {
77+
if (OS.isWindowsForSure()) {
78+
// For some reason windows can collide on debug port.
79+
assertThat(ASADMIN.exec("stop-domain"), asadminOK());
80+
assertThat(ASADMIN.exec("start-domain"), asadminOK());
81+
} else {
82+
assertThat(ASADMIN.exec("restart-domain"), asadminOK());
83+
}
7784
}
7885

7986
@Test

appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/StartServITest.java

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 Eclipse Foundation and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, 2025 Contributors to the Eclipse Foundation.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -13,6 +13,7 @@
1313
*
1414
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
1515
*/
16+
1617
package org.glassfish.main.admin.test;
1718

1819
import java.util.stream.Stream;
@@ -22,6 +23,7 @@
2223
import org.glassfish.main.itest.tools.asadmin.AsadminResult;
2324
import org.glassfish.main.itest.tools.asadmin.StartServ;
2425
import org.junit.jupiter.api.AfterAll;
26+
import org.junit.jupiter.api.AfterEach;
2527
import org.junit.jupiter.api.BeforeAll;
2628
import org.junit.jupiter.api.condition.DisabledOnOs;
2729
import org.junit.jupiter.api.extension.ExtensionContext;
@@ -54,29 +56,34 @@ static void setupDomain() {
5456
}
5557
}
5658

59+
@AfterEach
60+
void stopDomain() {
61+
ASADMIN.exec("stop-domain", STARTSERV_DOMAIN_NAME);
62+
}
63+
64+
@AfterAll
65+
static void deleteDomain() {
66+
AsadminResult result = ASADMIN.exec("list-domains");
67+
if (result.getOutput().contains(STARTSERV_DOMAIN_NAME)) {
68+
ASADMIN.exec("delete-domain", STARTSERV_DOMAIN_NAME);
69+
}
70+
}
71+
5772
@ParameterizedTest
5873
@ArgumentsSource(StartServArgumentsProvider.class)
5974
public void startServerInForeground(StartServ startServ) {
60-
try {
61-
AsadminResult result = startServ.withTextToWaitFor("Total startup time including CLI").exec(STARTSERV_DOMAIN_NAME);
62-
assertThat(result, asadminOK());
63-
} finally {
64-
ASADMIN.exec("stop-domain", STARTSERV_DOMAIN_NAME);
65-
}
75+
AsadminResult result = startServ.withTextToWaitFor("Total startup time including CLI").exec(STARTSERV_DOMAIN_NAME);
76+
assertThat(result, asadminOK());
6677
}
6778

6879
@ParameterizedTest
6980
@ArgumentsSource(StartServArgumentsProvider.class)
7081
@DisabledOnOs(value = WINDOWS, disabledReason = "startserv.bat is just trivial and doesn't give the error output")
7182
public void reportCorrectErrorIfAlreadyRunning(StartServ startServ) {
72-
try {
73-
AsadminResult result = startServ.withTextToWaitFor("Total startup time including CLI").exec(STARTSERV_DOMAIN_NAME);
74-
assertThat(result, asadminOK());
75-
result = startServ.withNoTextToWaitFor().exec(STARTSERV_DOMAIN_NAME);
76-
assertThat(result.getStdErr(), containsString("There is a process already using the admin port"));
77-
} finally {
78-
ASADMIN.exec("stop-domain", STARTSERV_DOMAIN_NAME);
79-
}
83+
AsadminResult result = startServ.withTextToWaitFor("Total startup time including CLI").exec(STARTSERV_DOMAIN_NAME);
84+
assertThat(result, asadminOK());
85+
result = startServ.withNoTextToWaitFor().exec(STARTSERV_DOMAIN_NAME);
86+
assertThat(result.getStdErr(), containsString("There is a process already using the admin port"));
8087
}
8188

8289
@ParameterizedTest
@@ -86,14 +93,6 @@ public void reportCorrectErrorIfInvalidCommand(StartServ startServ) {
8693
assertThat(result.getStdErr(), containsString("There is no such domain directory"));
8794
}
8895

89-
@AfterAll
90-
static void deleteDomain() {
91-
AsadminResult result = ASADMIN.exec("list-domains");
92-
if (result.getOutput().contains(STARTSERV_DOMAIN_NAME)) {
93-
ASADMIN.exec("delete-domain", STARTSERV_DOMAIN_NAME);
94-
}
95-
}
96-
9796
static class StartServArgumentsProvider implements ArgumentsProvider {
9897

9998
@Override

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
}

0 commit comments

Comments
 (0)