Initial Contribution Signed-off-by: Vinay Vishal <vinay.vishal@oracle.com>
diff --git a/appserver/core/javaee-kernel/pom.xml b/appserver/core/javaee-kernel/pom.xml new file mode 100755 index 0000000..6ad310a --- /dev/null +++ b/appserver/core/javaee-kernel/pom.xml
@@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Public License v. 2.0, which is available at + http://www.eclipse.org/legal/epl-2.0. + + This Source Code may also be made available under the following Secondary + Licenses when the conditions for such availability set forth in the + Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + version 2 with the GNU Classpath Exception, which is available at + https://www.gnu.org/software/classpath/license.html. + + SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.glassfish.main.core</groupId> + <artifactId>core</artifactId> + <version>5.0.1-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>javaee-kernel</artifactId> + <packaging>glassfish-jar</packaging> + + <name>Java EE related distributions kernel Classes</name> + + <developers> + <developer> + <id>dochez</id> + <name>Jerome Dochez</name> + <url>http://blogs.sun.com/dochez</url> + <organization>Oracle, Inc.</organization> + <roles> + <role>lead</role> + <role>developer</role> + </roles> + </developer> + </developers> + + <dependencies> + <dependency> + <groupId>org.glassfish.main.common</groupId> + <artifactId>glassfish-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.glassfish.main.common</groupId> + <artifactId>internal-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.glassfish.main.admin</groupId> + <artifactId>config-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.glassfish.hk2</groupId> + <artifactId>hk2-core</artifactId> + </dependency> + <dependency> + <groupId>org.glassfish.main.core</groupId> + <artifactId>kernel</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.glassfish.annotations</groupId> + <artifactId>logging-annotation-processor</artifactId> + <optional>true</optional> + </dependency> + </dependencies> +</project>
diff --git a/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/MEJBNamingObjectProxy.java b/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/MEJBNamingObjectProxy.java new file mode 100644 index 0000000..ec44fdf --- /dev/null +++ b/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/MEJBNamingObjectProxy.java
@@ -0,0 +1,112 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.kernel.javaee; + +import com.sun.enterprise.config.serverbeans.Server; +import com.sun.logging.LogDomains; +import org.glassfish.api.ActionReport; +import org.glassfish.api.admin.ServerEnvironment; +import org.glassfish.api.deployment.DeployCommandParameters; +import org.glassfish.api.naming.GlassfishNamingManager; +import org.glassfish.api.naming.NamingObjectProxy; +import org.glassfish.hk2.api.ServiceLocator; +import org.glassfish.internal.api.ServerContext; +import org.glassfish.internal.deployment.Deployment; +import org.glassfish.internal.deployment.ExtendedDeploymentContext; + +import javax.naming.Context; +import javax.naming.NamingException; +import java.io.File; +import java.io.IOException; +import java.util.logging.Logger; + + +/** + * Used to register MEJB for MEJB lazy initialization + */ +public class MEJBNamingObjectProxy implements NamingObjectProxy { + + private static final String NON_PORTABLE_MEJB_JNDI_NAME = "ejb/mgmt/MEJB"; + private static final String PORTABLE_MEJB_JNDI_NAME_SHORT = "java:global/mejb/MEJBBean"; + private static final String PORTABLE_MEJB_JNDI_NAME_LONG = + "java:global/mejb/MEJBBean!org.glassfish.admin.mejb.MEJBHome"; + + private static String[] jndiNames = new String[] + {NON_PORTABLE_MEJB_JNDI_NAME, + PORTABLE_MEJB_JNDI_NAME_SHORT, + PORTABLE_MEJB_JNDI_NAME_LONG}; + + private ServiceLocator habitat; + + private static final Logger _logger = LogDomains.getLogger( + MEJBNamingObjectProxy.class, LogDomains.EJB_LOGGER); + + + public MEJBNamingObjectProxy(ServiceLocator habitat) { + this.habitat = habitat; + } + + static String[] getJndiNames() { + return jndiNames; + } + + public Object create(Context ic) throws NamingException { + + Object mEJBHome = null; + try { + unpublishJndiNames(); + deployMEJB(); + mEJBHome = ic.lookup(NON_PORTABLE_MEJB_JNDI_NAME); + } catch (NamingException ne) { + throw ne; + } catch (Exception e) { + NamingException namingException = + new NamingException(e.getMessage()); + namingException.initCause(e); + throw namingException; + } + return mEJBHome; + } + + private void unpublishJndiNames() throws NamingException { + GlassfishNamingManager gfNamingManager = habitat.getService(GlassfishNamingManager.class); + for (String next : getJndiNames()) { + gfNamingManager.unpublishObject(next); + } + } + + private void deployMEJB() throws IOException { + _logger.info("Loading MEJB app on JNDI look up"); + ServerContext serverContext = habitat.getService(ServerContext.class); + File mejbArchive = new File(serverContext.getInstallRoot(), + "lib/install/applications/mejb.jar"); + DeployCommandParameters deployParams = + new DeployCommandParameters(mejbArchive); + String targetName = habitat.<Server>getService(Server.class, ServerEnvironment.DEFAULT_INSTANCE_NAME).getName(); + deployParams.target = targetName; + deployParams.name = "mejb"; + ActionReport report = habitat.getService(ActionReport.class, "plain"); + Deployment deployment = habitat.getService(Deployment.class); + ExtendedDeploymentContext dc = deployment.getBuilder(_logger, deployParams, report).source(mejbArchive).build(); + deployment.deploy(dc); + + if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) { + throw new RuntimeException("Failed to deploy MEJB app: " + + report.getFailureCause()); + } + } +}
diff --git a/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/MEJBService.java b/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/MEJBService.java new file mode 100755 index 0000000..ae55d4f --- /dev/null +++ b/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/MEJBService.java
@@ -0,0 +1,72 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.kernel.javaee; + +import javax.inject.Inject; +import javax.inject.Provider; + +import org.glassfish.hk2.runlevel.RunLevel; +import org.jvnet.hk2.annotations.Service; +import org.glassfish.hk2.api.PostConstruct; +import org.glassfish.hk2.api.ServiceLocator; +import org.glassfish.internal.api.InitRunLevel; +import org.glassfish.internal.api.Globals; +import org.glassfish.api.naming.GlassfishNamingManager; + +import com.sun.logging.LogDomains; + +import java.util.logging.Logger; +import java.util.logging.Level; + +/** + * MEJB service to register mejb with a temporary NamingObjectProxy at server + * start up time + */ +@Service +@RunLevel(InitRunLevel.VAL) +public class MEJBService implements PostConstruct { + + // we need to inject Globals as it used by the naming manager and + // therefore needs to be allocated. + @Inject + Globals globals; + + @Inject + ServiceLocator habitat; + + @Inject + Provider<GlassfishNamingManager> gfNamingManagerProvider; + + private static final Logger _logger = LogDomains.getLogger( + MEJBService.class, LogDomains.EJB_LOGGER); + + public void postConstruct() { + GlassfishNamingManager gfNamingManager = + gfNamingManagerProvider.get(); + + MEJBNamingObjectProxy mejbProxy = + new MEJBNamingObjectProxy(habitat); + for(String next : MEJBNamingObjectProxy.getJndiNames()) { + try { + gfNamingManager.publishObject(next, mejbProxy, true); + } catch (Exception e) { + _logger.log(Level.WARNING, "Problem in publishing temp proxy for MEJB: " + + e.getMessage(), e); + } + } + } +}
diff --git a/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/WebContainerStarter.java b/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/WebContainerStarter.java new file mode 100644 index 0000000..74b24f8 --- /dev/null +++ b/appserver/core/javaee-kernel/src/main/java/org/glassfish/kernel/javaee/WebContainerStarter.java
@@ -0,0 +1,352 @@ +/* + * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.kernel.javaee; + +import com.sun.enterprise.config.serverbeans.Config; +import com.sun.enterprise.config.serverbeans.ConfigBeansUtilities; +import com.sun.enterprise.config.serverbeans.Domain; +import com.sun.enterprise.config.serverbeans.HttpService; +import com.sun.enterprise.config.serverbeans.VirtualServer; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.v3.server.ContainerStarter; +import java.beans.PropertyChangeEvent; +import java.text.MessageFormat; +import java.util.Collection; +import java.util.List; +import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; +import org.glassfish.api.StartupRunLevel; +import org.glassfish.api.admin.ServerEnvironment; +import org.glassfish.api.container.Sniffer; +import org.glassfish.grizzly.config.dom.NetworkConfig; +import org.glassfish.grizzly.config.dom.NetworkListener; +import org.glassfish.grizzly.config.dom.NetworkListeners; +import org.glassfish.hk2.api.PostConstruct; +import org.glassfish.hk2.runlevel.RunLevel; +import org.glassfish.internal.data.ContainerRegistry; +import org.glassfish.internal.data.EngineInfo; +import org.glassfish.logging.annotation.LogMessageInfo; +import org.glassfish.logging.annotation.LogMessagesResourceBundle; +import org.glassfish.logging.annotation.LoggerInfo; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.config.Changed; +import org.jvnet.hk2.config.ConfigBeanProxy; +import org.jvnet.hk2.config.ConfigListener; +import org.jvnet.hk2.config.ConfigSupport; +import org.jvnet.hk2.config.NotProcessed; +import org.jvnet.hk2.config.ObservableBean; +import org.jvnet.hk2.config.UnprocessedChangeEvents; +import org.jvnet.hk2.config.types.Property; + +/** + * Startup service for the web container. + * + * This service checks if any domain.xml configuration, or changes in + * such configuration, that can be handled only by the web container + * (e.g., access logging) have been specified, and if so, starts the + * web container (unless already started). + * + * @author jluehe + */ +@Service +@RunLevel(StartupRunLevel.VAL) +public class WebContainerStarter + implements PostConstruct, ConfigListener { + + private static final String LOGMSG_PREFIX = "AS-CORE-JAVAEE"; + + @LogMessagesResourceBundle + private static final String SHARED_LOGMESSAGE_RESOURCE = "org.glassfish.kernel.javaee.LogMessages"; + + @LoggerInfo(subsystem = "AS-CORE", description = "Java EE Core Kernel", publish = true) + private static final String ASCORE_LOGGER = "javax.enterprise.system.core.ee"; + private static final Logger logger = Logger.getLogger( + ASCORE_LOGGER, SHARED_LOGMESSAGE_RESOURCE); + private static final ResourceBundle rb = logger.getResourceBundle(); + + @LogMessageInfo( + message = "Web Container not installed", + cause = "The web container does not install properly.", + action = "Please check the web container libraries are installed properly.", + level = "INFO") + public static final String mWebContainerNotInstalled = LOGMSG_PREFIX + "-0001"; + + @LogMessageInfo( + message = "Done with starting {0} container.", + level = "INFO") + public static final String mStartContainerDone = LOGMSG_PREFIX + "-0002"; + + @LogMessageInfo( + message = "Unable to start container (no exception provided)", + cause = "The web container does not start properly.", + action = "Please check the web container libraries are installed properly.", + level = "SEVERE") + public static final String mUnableStartContainerNoException = LOGMSG_PREFIX + "-0003"; + + @LogMessageInfo( + message = "Unable to start container {0}", + cause = "The web container does not start properly. Most probably, there is a class loading issue.", + action = "Please resolve issues mentioned in the stack trace.", + level = "SEVERE") + public static final String mUnableStartContainer = LOGMSG_PREFIX + "-0004"; + + private static final String AUTH_PASSTHROUGH_ENABLED_PROP = + "authPassthroughEnabled"; + + private static final String PROXY_HANDLER_PROP = "proxyHandler"; + + private static final String TRACE_ENABLED_PROP = "traceEnabled"; + + @Inject + private Provider<Domain> domainProvider; + + @Inject + private ContainerRegistry containerRegistry; + + @Inject + private ContainerStarter containerStarter; + + @Inject + private ModulesRegistry modulesRegistry; + + @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME) + private Provider<Config> serverConfigProvider; + + @Inject @Named("web") + private Provider<Sniffer> webSnifferProvider; + + /** + * Scans the domain.xml to see if it specifies any configuration + * that can be handled only by the web container, and if so, starts + * the web container + */ + public void postConstruct() { + domainProvider.get(); + Config serverConfig = serverConfigProvider.get(); + + boolean isStartNeeded = false; + if (serverConfig != null) { + if (isStartNeeded(serverConfig.getHttpService())) { + isStartNeeded = true; + } + if (!isStartNeeded && isStartNeeded(serverConfig.getNetworkConfig())) { + isStartNeeded = true; + } + } + + if (isStartNeeded) { + startWebContainer(); + } else { + ObservableBean bean = (ObservableBean) ConfigSupport.getImpl(serverConfig.getHttpService()); + bean.addListener(this); + bean = (ObservableBean) ConfigSupport.getImpl(serverConfig.getNetworkConfig().getNetworkListeners()); + bean.addListener(this); + } + } + + public UnprocessedChangeEvents changed(PropertyChangeEvent[] events) { + return ConfigSupport.sortAndDispatch(events, new Changed() { + public <T extends ConfigBeanProxy> NotProcessed changed( + TYPE type, Class<T> tClass, T t) { + if (tClass == HttpService.class) { + if (type == TYPE.CHANGE) { + if (isStartNeeded((HttpService) t)) { + startWebContainer(); + } + } + } else if (tClass == VirtualServer.class) { + if (type == TYPE.ADD || type == TYPE.CHANGE) { + if (isStartNeeded((VirtualServer) t)) { + startWebContainer(); + } + } + } else if (tClass == NetworkListener.class) { + if (type == TYPE.ADD || type == TYPE.CHANGE) { + if (isStartNeeded((NetworkListener) t)) { + startWebContainer(); + } + } + } + return null; + } + } + , logger); + } + + /** + * Starts the web container + */ + private void startWebContainer() { + Sniffer webSniffer = webSnifferProvider.get(); + if (webSniffer==null) { + if (logger.isLoggable(Level.INFO)) { + logger.info(mWebContainerNotInstalled); + } + return; + } + + if (containerRegistry.getContainer( + webSniffer.getContainersNames()[0]) != null) { + containerRegistry.getContainer( + webSniffer.getContainersNames()[0]).getContainer(); + } else { + try { + Collection<EngineInfo> containersInfo = + containerStarter.startContainer(webSniffer); + if (containersInfo != null && !containersInfo.isEmpty()) { + // Start each container + for (EngineInfo info : containersInfo) { + info.getContainer(); + if (logger.isLoggable(Level.INFO)) { + logger.log(Level.INFO, mStartContainerDone, + webSniffer.getModuleType()); + } + } + } else { + logger.severe(mUnableStartContainerNoException); + } + } catch (Exception e) { + String msg; + if ( rb != null ) { + msg = MessageFormat.format( rb.getString(mUnableStartContainer), webSniffer.getContainersNames()[0]); + } else { + msg = "Unable to start Web Container: " + webSniffer.getContainersNames()[0]; + } + logger.log(Level.SEVERE, msg, e); + } + } + } + + /* + * @return true if the given HttpService contains any configuration + * that can be handled only by the web container and therefore requires + * the web container to be started, false otherwise + */ + private boolean isStartNeeded(HttpService httpService) { + if (httpService == null) { + return false; + } + + if (ConfigBeansUtilities.toBoolean( + httpService.getAccessLoggingEnabled()) || + ConfigBeansUtilities.toBoolean( + httpService.getSsoEnabled())) { + return true; + } + + List<Property> props = httpService.getProperty(); + if (props != null) { + for (Property prop : props) { + String propName = prop.getName(); + String propValue = prop.getValue(); + if (AUTH_PASSTHROUGH_ENABLED_PROP.equals(propName)) { + if (ConfigBeansUtilities.toBoolean(propValue)) { + return true; + } + } else if (PROXY_HANDLER_PROP.equals(propName)) { + return true; + } else if (TRACE_ENABLED_PROP.equals(propName)) { + if (!ConfigBeansUtilities.toBoolean(propValue)) { + return true; + } + } + } + } + + List<VirtualServer> hosts = httpService.getVirtualServer(); + if (hosts != null) { + for (VirtualServer host : hosts) { + if (isStartNeeded(host)) { + return true; + } + } + } + + return false; + } + + /* + * @return true if the given VirtualServer contains any configuration + * that can be handled only by the web container and therefore requires + * the web container to be started, false otherwise + */ + private boolean isStartNeeded(VirtualServer host) { + if (host == null) { + return false; + } + + if (ConfigBeansUtilities.toBoolean(host.getAccessLoggingEnabled()) || + ConfigBeansUtilities.toBoolean(host.getSsoEnabled())) { + return true; + } + + String state = host.getState(); + if (state != null && + ("disabled".equals(state) || + !ConfigBeansUtilities.toBoolean(state))) { + return true; + } + + List<Property> props = host.getProperty(); + if (props != null && !props.isEmpty()) { + return true; + } + + return false; + } + + /* + * @return true if the given NetworkConfig contains any configuration + * that can be handled only by the web container and therefore requires + * the web container to be started, false otherwise + */ + private boolean isStartNeeded(NetworkConfig networkConfig) { + if (networkConfig == null) { + return false; + } + + NetworkListeners networkListeners = networkConfig.getNetworkListeners(); + if (networkListeners == null) { + return false; + } + + for (NetworkListener networkListener : networkListeners.getNetworkListener()) { + if (isStartNeeded(networkListener)) { + return true; + } + } + + return false; + } + + /* + * @return true if the given NetworkListener contains any configuration + * that can be handled only by the web container and therefore requires + * the web container to be started, false otherwise + */ + private boolean isStartNeeded(NetworkListener networkListener) { + if (networkListener == null) { + return false; + } + + return ConfigBeansUtilities.toBoolean(networkListener.getJkEnabled()); + } +}