Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GlassFishORBHelper changed to singleton, lifecycle #24806

Merged
merged 4 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation.
* Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation.
* Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand All @@ -19,6 +19,9 @@

import com.sun.logging.LogDomains;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.ejb.Singleton;
import jakarta.inject.Inject;
import jakarta.inject.Provider;

Expand All @@ -29,27 +32,24 @@
import java.util.logging.Logger;

import org.glassfish.api.admin.ProcessEnvironment;
import org.glassfish.api.event.EventListener;
import org.glassfish.api.event.Events;
import org.glassfish.api.naming.GlassfishNamingManager;
import org.glassfish.hk2.api.PostConstruct;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.internal.api.ORBLocator;
import org.jvnet.hk2.annotations.Service;
import org.omg.CORBA.ORB;
import org.omg.PortableInterceptor.ServerRequestInfo;

import static com.sun.logging.LogDomains.CORBA_LOGGER;
import static org.glassfish.api.event.EventTypes.SERVER_SHUTDOWN;

/**
* This class exposes any orb/iiop functionality needed by modules in the app server. This prevents modules from needing
* any direct dependencies on the orb-iiop module.
* This class exposes any orb/iiop functionality needed by modules in the app server.
* This prevents modules from needing any direct dependencies on the orb-iiop module.
*
* @author Mahesh Kannan Date: Jan 17, 2009
* @author Mahesh Kannan, Jan 17, 2009
*/
@Service
public class GlassFishORBHelper implements PostConstruct, ORBLocator {
@Singleton
public class GlassFishORBHelper implements ORBLocator {

private static final Logger LOG = LogDomains.getLogger(GlassFishORBHelper.class, CORBA_LOGGER, false);

Expand All @@ -60,43 +60,38 @@ public class GlassFishORBHelper implements PostConstruct, ORBLocator {
private ProcessEnvironment processEnv;

@Inject
Provider<ProtocolManager> protocolManagerProvider;
private Provider<ProtocolManager> protocolManagerProvider;

@Inject
Provider<GlassfishNamingManager> glassfishNamingManagerProvider;

@Inject
private Provider<Events> eventsProvider;

private volatile ORB orb;
private Provider<GlassfishNamingManager> glassfishNamingManagerProvider;

private ProtocolManager protocolManager;

private SelectableChannelDelegate selectableChannelDelegate;

private GlassFishORBFactory orbFactory;

@Override
// volatile is enough for sync, just one thread can write
private volatile ORB orb;
private volatile boolean destroyed;

@PostConstruct
public void postConstruct() {
orbFactory = services.getService(GlassFishORBFactory.class);
}

@PreDestroy
public void onShutdown() {
LOG.log(Level.FINE, "ORB Shutdown started");
orb.destroy();
// FIXME: getORB is able to create another, it should be refactored and simplified.
destroyed = true;
LOG.log(Level.CONFIG, "ORB Shutdown started");
if (orb != null) {
orb.destroy();
orb = null;
}
}

// Called by PEORBConfigurator executed from glassfish-corba-orb.jar
public synchronized void setORB(ORB orb) {
this.orb = orb;

if (orb != null) {
EventListener glassfishEventListener = event -> {
if (event.is(SERVER_SHUTDOWN)) {
onShutdown();
}
};
eventsProvider.get().register(glassfishEventListener);
}
}

/**
Expand All @@ -108,55 +103,58 @@ public ORB getORB() {
// Use a volatile double-checked locking idiom here so that we can publish
// a partly-initialized ORB early, so that lazy init can come into getORB()
// and allow an invocation to the transport to complete.
if (orb == null) {

synchronized (this) {
if (orb == null) {
try {
boolean isServer = processEnv.getProcessType().isServer();

Properties props = new Properties();
props.setProperty(GlassFishORBFactory.ENV_IS_SERVER_PROPERTY, Boolean.valueOf(isServer).toString());

// Create orb and make it visible.
//
// This will allow loopback calls to getORB() from portable interceptors activated as a
// side-effect of the remaining initialization.
//
// If it's a server, there's a small time window during which the ProtocolManager won't be available.
// Any callbacks that result from the protocol manager initialization itself cannot depend on having
// access to the protocol manager.
orb = orbFactory.createORB(props);

if (isServer) {
if (protocolManager == null) {
ProtocolManager tempProtocolManager = protocolManagerProvider.get();

tempProtocolManager.initialize(orb);

// Move startup of naming to PEORBConfigurator so it runs before interceptors.
tempProtocolManager.initializePOAs();

// Now make protocol manager visible.
protocolManager = tempProtocolManager;

GlassfishNamingManager namingManager = glassfishNamingManagerProvider.get();

Remote remoteSerialProvider = namingManager.initializeRemoteNamingSupport(orb);

protocolManager.initializeRemoteNaming(remoteSerialProvider);
}
}
} catch (Exception e) {
orb = null;
protocolManager = null;
throw new RuntimeException("Orb initialization erorr", e);
}
{
final ORB orbInstance = this.orb;
if (orbInstance != null || destroyed) {
return orbInstance;
}
}
synchronized (this) {
if (this.orb != null) {
return this.orb;
}
try {
final boolean isServer = processEnv.getProcessType().isServer();

final Properties props = new Properties();
props.setProperty(GlassFishORBFactory.ENV_IS_SERVER_PROPERTY, Boolean.toString(isServer));

// Create orb and make it visible.
//
// This will allow loopback calls to getORB() from portable interceptors activated
// as a side-effect of the remaining initialization.
//
// If it's a server, there's a small time window during which the ProtocolManager
// won't be available.
// Any callbacks that result from the protocol manager initialization itself cannot
// depend on having access to the protocol manager.
orb = orbFactory.createORB(props);

if (!isServer || protocolManager != null) {
return orb;
}
protocolManager = initProtocolManager(orb);
return orb;
avpinchuk marked this conversation as resolved.
Show resolved Hide resolved
} catch (Exception e) {
orb = null;
protocolManager = null;
throw new RuntimeException("Orb initialization erorr", e);
}
}
}

return orb;

private ProtocolManager initProtocolManager(final ORB orbInstance) throws Exception {
final ProtocolManager manager = protocolManagerProvider.get();
manager.initialize(orbInstance);

// Move startup of naming to PEORBConfigurator so it runs before interceptors.
manager.initializePOAs();

final GlassfishNamingManager namingManager = glassfishNamingManagerProvider.get();
final Remote remoteSerialProvider = namingManager.initializeRemoteNamingSupport(orbInstance);
manager.initializeRemoteNaming(remoteSerialProvider);
return manager;
}

public void setSelectableChannelDelegate(SelectableChannelDelegate d) {
Expand All @@ -167,33 +165,28 @@ public SelectableChannelDelegate getSelectableChannelDelegate() {
return this.selectableChannelDelegate;
}

public interface SelectableChannelDelegate {
void handleRequest(SelectableChannel channel);
}

/**
* Get a protocol manager for creating remote references. ProtocolManager is only available in the server. Otherwise,
* this method returns null.
*
* If it's the server and the orb hasn't been already created, calling this method has the side effect of creating the
* orb.
* Get a protocol manager for creating remote references.
* ProtocolManager is only available in the server.
* Otherwise, this method returns null.
* If it's the server and the orb hasn't been already created, calling this method has the side
* effect of creating the orb.
*/
public ProtocolManager getProtocolManager() {
if (!processEnv.getProcessType().isServer()) {
if (!processEnv.getProcessType().isServer() || destroyed) {
return null;
}

synchronized (this) {
if (protocolManager == null) {
getORB();
}

return protocolManager;
}
}

public boolean isORBInitialized() {
return (orb != null);
return orb != null;
}

public int getOTSPolicyType() {
Expand Down Expand Up @@ -230,4 +223,7 @@ public boolean isEjbCall(ServerRequestInfo sri) {
return orbFactory.isEjbCall(sri);
}

public interface SelectableChannelDelegate {
void handleRequest(SelectableChannel channel);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation.
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand All @@ -16,48 +17,40 @@

package org.glassfish.enterprise.iiop.api;

import java.rmi.*;

import org.glassfish.enterprise.iiop.spi.EjbContainerFacade;
import org.glassfish.enterprise.iiop.spi.EjbService;

import com.sun.enterprise.deployment.EjbDescriptor;

import java.rmi.Remote;
import java.rmi.RemoteException;

import org.glassfish.enterprise.iiop.spi.EjbContainerFacade;
import org.jvnet.hk2.annotations.Contract;
import org.omg.CORBA.ORB;
import java.rmi.Remote;


/**
* The ProtocolManager interface specifies the functionality of the
* remote communication layer, which provides the support for
* distribution described in Chapter 13 of the EJB spec.
* Possible implementations of the ProtocolManager include RMI/IIOP,
* RMI/JRMP, RMI/DCOM, RMI/HTTP ....
* The ProtocolManager interface specifies the functionality of the remote communication layer,
* which provides the support for distribution described in Chapter 13 of the EJB spec.
* Possible implementations of the ProtocolManager include RMI/IIOP, RMI/JRMP, RMI/DCOM, RMI/HTTP,
* etc.
*
* @author Vivek Nagar
*/

@Contract
public interface ProtocolManager {

void initialize(ORB o);

void initializePOAs() throws Exception;

public void initializePOAs() throws Exception;

void initializeNaming() throws Exception;

public void initializeNaming() throws Exception;

public void initializeRemoteNaming(Remote remoteNamingProvider) throws Exception;
void initializeRemoteNaming(Remote remoteNamingProvider) throws Exception;

/**
* Return a factory that can be used to create/destroy remote
* references for a particular EJB type.
*/
RemoteReferenceFactory getRemoteReferenceFactory(EjbContainerFacade container,
boolean remoteHomeView,
String id);

RemoteReferenceFactory getRemoteReferenceFactory(EjbContainerFacade container, boolean remoteHomeView, String id);

/**
* Return true if the two object references refer to the same
Expand Down Expand Up @@ -91,9 +84,5 @@ RemoteReferenceFactory getRemoteReferenceFactory(EjbContainerFacade container,
*/
void connectObject(Remote remoteObj) throws RemoteException;


EjbDescriptor getEjbDescriptor(byte[] ejbKey);

}


Loading