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());
+ }
+}