Initial Contribution

Signed-off-by: Vinay Vishal <vinay.vishal@oracle.com>
diff --git a/appserver/resources/resources-runtime/osgi.bundle b/appserver/resources/resources-runtime/osgi.bundle
new file mode 100644
index 0000000..79376aa
--- /dev/null
+++ b/appserver/resources/resources-runtime/osgi.bundle
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2011, 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
+#
+
+-exportcontents: \
+                 org.glassfish.resources.deployer; \
+                 org.glassfish.resources.beans; \
+                 org.glassfish.resources.module; version=${project.osgi.version}
diff --git a/appserver/resources/resources-runtime/pom.xml b/appserver/resources/resources-runtime/pom.xml
new file mode 100755
index 0000000..34607f0
--- /dev/null
+++ b/appserver/resources/resources-runtime/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2011, 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">
+    <parent>
+        <groupId>org.glassfish.main.resources</groupId>
+        <artifactId>resources</artifactId>
+        <version>5.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>resources-runtime</artifactId>
+    <packaging>glassfish-jar</packaging>
+    
+    <name>GlassFish resources runtime</name>
+
+    <developers>
+        <developer>
+            <id>jr158900</id>
+            <name>Jagadish Ramu</name>
+            <url>http://blogs.sun.com/JagadishPrasath</url>
+            <organization>Oracle, Inc.</organization>
+            <roles>
+                <role>developer</role>
+            </roles>
+        </developer>
+    </developers>
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                </includes>
+            </resource>
+             <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+        </resources>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>hk2-core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.main.deployment</groupId>
+            <artifactId>dol</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.main.resources</groupId>
+            <artifactId>resources-connector</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>glassfish-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.main.deployment</groupId>
+            <artifactId>deployment-javaee-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
+
diff --git a/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/beans/CustomResource.java b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/beans/CustomResource.java
new file mode 100755
index 0000000..4db75a4
--- /dev/null
+++ b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/beans/CustomResource.java
@@ -0,0 +1,68 @@
+/*
+ * 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.resources.beans;
+
+import org.glassfish.resources.api.JavaEEResource;
+import org.glassfish.resources.api.JavaEEResourceBase;
+import org.glassfish.resourcebase.resources.api.ResourceInfo;
+
+/**
+ * Resource info for CustomResourcel.
+ * IASRI #4626188
+ *
+ * @author Sridatta Viswanath
+ */
+public class CustomResource extends JavaEEResourceBase {
+
+    private String resType_;
+    private String factoryClass_;
+
+    public CustomResource(ResourceInfo resourceInfo) {
+        super(resourceInfo);
+    }
+
+    protected JavaEEResource doClone(ResourceInfo resourceInfo) {
+        CustomResource clone = new CustomResource(resourceInfo);
+        clone.setResType(getResType());
+        clone.setFactoryClass(getFactoryClass());
+        return clone;
+    }
+
+    public int getType() {
+        return JavaEEResource.CUSTOM_RESOURCE;
+    }
+
+    public String getResType() {
+        return resType_;
+    }
+
+    public void setResType(String resType) {
+        resType_ = resType;
+    }
+
+    public String getFactoryClass() {
+        return factoryClass_;
+    }
+
+    public void setFactoryClass(String factoryClass) {
+        factoryClass_ = factoryClass;
+    }
+
+    public String toString() {
+        return "< Custom Resource : " + getResourceInfo() + " , " + getResType() + "... >";
+    }
+}
diff --git a/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/beans/ExternalJndiResource.java b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/beans/ExternalJndiResource.java
new file mode 100755
index 0000000..71a767d
--- /dev/null
+++ b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/beans/ExternalJndiResource.java
@@ -0,0 +1,89 @@
+/*
+ * 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.resources.beans;
+
+import org.glassfish.resources.api.JavaEEResource;
+import org.glassfish.resources.api.JavaEEResourceBase;
+import org.glassfish.resourcebase.resources.api.ResourceConstants;
+import org.glassfish.resourcebase.resources.api.ResourceInfo;
+
+/**
+ * Resource info for ExternalJndiResource.
+ * IASRI #4626188
+ * <p><b>NOT THREAD SAFE: mutable instance variables</b>
+ *
+ * @author Sridatta Viswanath
+ */
+public class ExternalJndiResource extends JavaEEResourceBase {
+
+    private String jndiLookupName_;
+    private String resType_;
+    private String factoryClass_;
+
+    public ExternalJndiResource(ResourceInfo resourceInfo) {
+        super(resourceInfo);
+    }
+
+    protected JavaEEResource doClone(ResourceInfo resourceInfo) {
+        ExternalJndiResource clone = new ExternalJndiResource(resourceInfo);
+        clone.setJndiLookupName(getJndiLookupName());
+        clone.setResType(getResType());
+        clone.setFactoryClass(getFactoryClass());
+        return clone;
+    }
+
+    public int getType() {
+        return JavaEEResource.EXTERNAL_JNDI_RESOURCE;
+    }
+
+    public String getJndiLookupName() {
+        return jndiLookupName_;
+    }
+
+    public void setJndiLookupName(String jndiLookupName) {
+        jndiLookupName_ = jndiLookupName;
+    }
+
+    public String getResType() {
+        return resType_;
+    }
+
+    public void setResType(String resType) {
+        resType_ = resType;
+    }
+
+    public String getFactoryClass() {
+        return factoryClass_;
+    }
+
+    public void setFactoryClass(String factoryClass) {
+        factoryClass_ = factoryClass;
+    }
+
+    //START OF IASRI 4660565
+    public boolean isJMSConnectionFactory() {
+        if (resType_ == null) return false;
+
+        return (ResourceConstants.JMS_QUEUE_CONNECTION_FACTORY.equals(resType_) ||
+                ResourceConstants.JMS_TOPIC_CONNECTION_FACTORY.equals(resType_));
+    }
+    //END OF IASRI 4660565
+
+    public String toString() {
+        return "< External Jndi Resource : " + getResourceInfo() + " , " + getJndiLookupName() + "... >";
+    }
+}
diff --git a/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/deployer/CustomResourceDeployer.java b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/deployer/CustomResourceDeployer.java
new file mode 100644
index 0000000..2be88eb
--- /dev/null
+++ b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/deployer/CustomResourceDeployer.java
@@ -0,0 +1,294 @@
+/*
+ * 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.resources.deployer;
+
+import com.sun.enterprise.config.serverbeans.Application;
+import com.sun.enterprise.config.serverbeans.Resource;
+import com.sun.enterprise.config.serverbeans.Resources;
+import com.sun.enterprise.repository.ResourceProperty;
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.logging.LogDomains;
+import org.glassfish.resources.api.*;
+import org.glassfish.resources.config.CustomResource;
+import org.jvnet.hk2.annotations.Service;
+import org.jvnet.hk2.config.types.Property;
+import org.glassfish.resourcebase.resources.api.ResourceInfo;
+import org.glassfish.resourcebase.resources.api.ResourceDeployer;
+import org.glassfish.resourcebase.resources.api.ResourceConflictException;
+import org.glassfish.resourcebase.resources.api.ResourceDeployerInfo;
+import org.glassfish.resourcebase.resources.util.ResourceUtil;
+import org.glassfish.resourcebase.resources.util.BindableResourcesHelper;
+import org.glassfish.resourcebase.resources.naming.ResourceNamingService;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Handles custom resource events in the server instance.
+ * <p/>
+ * The custom resource events from the admin instance are propagated
+ * to this object.
+ * <p/>
+ * The methods can potentially be called concurrently, therefore implementation
+ * need to be synchronized.
+ * <p/>
+ * <p/>
+ * Note: Since a notification is not sent to the user of the custom
+ * resources upon undeploy, it is possible that there would be
+ * stale objects not being garbage collected. Future versions
+ * should take care of this problem.
+ *
+ * @author Nazrul Islam
+ * @since JDK1.4
+ */
+@Service
+@ResourceDeployerInfo(CustomResource.class)
+@Singleton
+public class CustomResourceDeployer implements ResourceDeployer {
+
+
+    @Inject
+    private BindableResourcesHelper bindableResourcesHelper;
+
+    /**
+     * Stringmanager for this deployer
+     */
+    private static final StringManager localStrings =
+            StringManager.getManager(CustomResourceDeployer.class);
+
+    @Inject
+    private ResourceNamingService cns;
+    /**
+     * logger for this deployer
+     */
+    private static Logger _logger = LogDomains.getLogger(CustomResourceDeployer.class, LogDomains.RSR_LOGGER);
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void deployResource(Object resource, String applicationName, String moduleName)
+            throws Exception {
+        CustomResource customResource =
+                (CustomResource) resource;
+        ResourceInfo resourceInfo = new ResourceInfo(customResource.getJndiName(), applicationName, moduleName);
+        deployResource(resource, resourceInfo);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void deployResource(Object resource) throws Exception {
+        CustomResource customResource =
+                (CustomResource) resource;
+        ResourceInfo resourceInfo = ResourceUtil.getResourceInfo(customResource);
+        deployResource(customResource, resourceInfo);
+    }
+
+    private void deployResource(Object resource, ResourceInfo resourceInfo) {
+
+        CustomResource customRes =
+                (CustomResource) resource;
+
+        // converts the config data to j2ee resource
+        JavaEEResource j2eeResource = toCustomJavaEEResource(customRes, resourceInfo);
+
+        // installs the resource
+        installCustomResource((org.glassfish.resources.beans.CustomResource) j2eeResource, resourceInfo);
+
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void undeployResource(Object resource, String applicationName, String moduleName) throws Exception {
+        CustomResource customResource =
+                (CustomResource) resource;
+        ResourceInfo resourceInfo = new ResourceInfo(customResource.getJndiName(), applicationName, moduleName);
+        deleteResource(customResource, resourceInfo);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void undeployResource(Object resource)
+            throws Exception {
+
+        CustomResource customResource =
+                (CustomResource) resource;
+        ResourceInfo resourceInfo = ResourceUtil.getResourceInfo(customResource);
+        deleteResource(customResource, resourceInfo);
+    }
+
+    private void deleteResource(CustomResource customResource,
+                                ResourceInfo resourceInfo) throws NamingException {
+        // converts the config data to j2ee resource
+        //JavaEEResource j2eeResource = toCustomJavaEEResource(customRes, resourceInfo);
+        // removes the resource from jndi naming
+        cns.unpublishObject(resourceInfo, resourceInfo.getName());
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean handles(Object resource) {
+        return resource instanceof CustomResource;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public boolean supportsDynamicReconfiguration() {
+        return false;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Class[] getProxyClassesForDynamicReconfiguration() {
+        return new Class[0];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void redeployResource(Object resource)
+            throws Exception {
+
+        undeployResource(resource);
+        deployResource(resource);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void enableResource(Object resource) throws Exception {
+        deployResource(resource);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void disableResource(Object resource) throws Exception {
+        undeployResource(resource);
+    }
+
+    /**
+     * Installs the given custom resource. It publishes the resource as a
+     * javax.naming.Reference with the naming manager (jndi). This method gets
+     * called during server initialization and custom resource deployer to
+     * handle custom resource events.
+     *
+     * @param customRes custom resource
+     */
+    public void installCustomResource(org.glassfish.resources.beans.CustomResource customRes, ResourceInfo resourceInfo) {
+
+        try {
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.log(Level.FINE, "installCustomResource by jndi-name : " + resourceInfo);
+            }
+
+            // bind a Reference to the object factory
+            Reference ref = new Reference(customRes.getResType(), customRes.getFactoryClass(), null);
+
+            // add resource properties as StringRefAddrs
+            for (Iterator props = customRes.getProperties().iterator();
+                 props.hasNext(); ) {
+
+                ResourceProperty prop = (ResourceProperty) props.next();
+
+                ref.add(new StringRefAddr(prop.getName(),
+                        (String) prop.getValue()));
+            }
+
+            // publish the reference
+            cns.publishObject(resourceInfo, ref, true);
+        } catch (Exception ex) {
+            _logger.log(Level.SEVERE, "customrsrc.create_ref_error", resourceInfo);
+            _logger.log(Level.SEVERE, "customrsrc.create_ref_error_excp", ex);
+        }
+    }
+
+    /**
+     * Returns a new instance of j2ee custom resource from the given
+     * config bean.
+     * <p/>
+     * This method gets called from the custom resource deployer
+     * to convert custom-resource config bean into custom j2ee resource.
+     *
+     * @param rbean custom-resource config bean
+     * @return new instance of j2ee custom resource
+     */
+    public static JavaEEResource toCustomJavaEEResource(
+            CustomResource rbean, ResourceInfo resourceInfo) {
+
+
+        org.glassfish.resources.beans.CustomResource jr =
+                new org.glassfish.resources.beans.CustomResource(resourceInfo);
+
+        //jr.setDescription(rbean.getDescription()); // FIXME: getting error
+
+        // sets the enable flag
+        jr.setEnabled(Boolean.valueOf(rbean.getEnabled()));
+
+        // sets the resource type
+        jr.setResType(rbean.getResType());
+
+        // sets the factory class name
+        jr.setFactoryClass(rbean.getFactoryClass());
+
+        // sets the properties
+        List<Property> properties = rbean.getProperty();
+        if (properties != null) {
+            for (Property property : properties) {
+                ResourceProperty rp =
+                        new ResourcePropertyImpl(property.getName(), property.getValue());
+                jr.addProperty(rp);
+            }
+        }
+        return jr;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean canDeploy(boolean postApplicationDeployment, Collection<Resource> allResources, Resource resource) {
+        if (handles(resource)) {
+            if (!postApplicationDeployment) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void validatePreservedResource(Application oldApp, Application newApp, Resource resource,
+                                          Resources allResources)
+            throws ResourceConflictException {
+        //do nothing.
+    }
+}
diff --git a/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/deployer/ExternalJndiResourceDeployer.java b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/deployer/ExternalJndiResourceDeployer.java
new file mode 100644
index 0000000..6d584ef
--- /dev/null
+++ b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/deployer/ExternalJndiResourceDeployer.java
@@ -0,0 +1,375 @@
+/*
+ * 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.resources.deployer;
+
+import com.sun.enterprise.config.serverbeans.Application;
+import com.sun.enterprise.config.serverbeans.Resource;
+import com.sun.enterprise.config.serverbeans.Resources;
+import com.sun.enterprise.repository.ResourceProperty;
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.logging.LogDomains;
+import org.glassfish.resources.api.*;
+import org.glassfish.resources.config.ExternalJndiResource;
+import org.glassfish.resources.naming.JndiProxyObjectFactory;
+import org.glassfish.resources.naming.ProxyRefAddr;
+import org.glassfish.resourcebase.resources.naming.ResourceNamingService;
+import org.glassfish.resources.naming.SerializableObjectRefAddr;
+import org.glassfish.resourcebase.resources.util.BindableResourcesHelper;
+import org.glassfish.resourcebase.resources.util.ResourceUtil;
+import org.glassfish.resourcebase.resources.api.ResourceInfo;
+import org.glassfish.resourcebase.resources.api.ResourceDeployer;
+import org.glassfish.resourcebase.resources.api.ResourceDeployerInfo;
+import org.glassfish.resourcebase.resources.api.ResourceConflictException;
+import org.jvnet.hk2.annotations.Service;
+import javax.inject.Singleton;
+import org.jvnet.hk2.config.types.Property;
+
+import javax.inject.Inject;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+import javax.naming.spi.InitialContextFactory;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Handles external-jndi resource events in the server instance.
+ * <p/>
+ * The external-jndi resource events from the admin instance are propagated
+ * to this object.
+ * <p/>
+ * The methods can potentially be called concurrently, therefore implementation
+ * need to be synchronized.
+ *
+ * @author Nazrul Islam
+ * @since JDK1.4
+ */
+@Service
+@ResourceDeployerInfo(ExternalJndiResource.class)
+@Singleton
+public class ExternalJndiResourceDeployer implements ResourceDeployer {
+
+    @Inject
+    private ResourceNamingService namingService;
+
+    @Inject
+    private BindableResourcesHelper bindableResourcesHelper;
+
+
+    /**
+     * StringManager for this deployer
+     */
+    private static final StringManager localStrings =
+            StringManager.getManager(ExternalJndiResourceDeployer.class);
+    /**
+     * logger for this deployer
+     */
+    private static Logger _logger = LogDomains.getLogger(ExternalJndiResourceDeployer.class, LogDomains.RSR_LOGGER);
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void deployResource(Object resource, String applicationName, String moduleName) throws Exception {
+        ExternalJndiResource jndiRes =
+                (ExternalJndiResource) resource;
+        ResourceInfo resourceInfo = new ResourceInfo(jndiRes.getJndiName(), applicationName, moduleName);
+        createExternalJndiResource(jndiRes, resourceInfo);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void deployResource(Object resource) throws Exception {
+
+        ExternalJndiResource jndiRes =
+                (ExternalJndiResource) resource;
+        ResourceInfo resourceInfo = ResourceUtil.getResourceInfo(jndiRes);
+        createExternalJndiResource(jndiRes, resourceInfo);
+    }
+
+    private void createExternalJndiResource(ExternalJndiResource jndiRes,
+                                            ResourceInfo resourceInfo) {
+        // converts the config data to j2ee resource
+        JavaEEResource j2eeRes = toExternalJndiJavaEEResource(jndiRes, resourceInfo);
+
+        // installs the resource
+        installExternalJndiResource((org.glassfish.resources.beans.ExternalJndiResource) j2eeRes, resourceInfo);
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void undeployResource(Object resource, String applicationName, String moduleName) throws Exception {
+        ExternalJndiResource jndiRes =
+                (ExternalJndiResource) resource;
+        ResourceInfo resourceInfo = new ResourceInfo(jndiRes.getJndiName(), applicationName, moduleName);
+        deleteResource(jndiRes, resourceInfo);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void undeployResource(Object resource)
+            throws Exception {
+
+        ExternalJndiResource jndiRes =
+                (ExternalJndiResource) resource;
+        ResourceInfo resourceInfo = ResourceUtil.getResourceInfo(jndiRes);
+        deleteResource(jndiRes, resourceInfo);
+    }
+
+    private void deleteResource(ExternalJndiResource jndiResource,
+                                ResourceInfo resourceInfo) {
+        // converts the config data to j2ee resource
+        JavaEEResource j2eeResource = toExternalJndiJavaEEResource(jndiResource, resourceInfo);
+        // un-installs the resource
+        uninstallExternalJndiResource(j2eeResource, resourceInfo);
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void redeployResource(Object resource)
+            throws Exception {
+
+        undeployResource(resource);
+        deployResource(resource);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean handles(Object resource) {
+        return resource instanceof ExternalJndiResource;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public boolean supportsDynamicReconfiguration() {
+        return false;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Class[] getProxyClassesForDynamicReconfiguration() {
+        return new Class[0];
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void enableResource(Object resource) throws Exception {
+        deployResource(resource);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void disableResource(Object resource) throws Exception {
+        undeployResource(resource);
+    }
+
+    /**
+     * Installs the given external jndi resource. This method gets called
+     * during server initialization and from external jndi resource
+     * deployer to handle resource events.
+     *
+     * @param extJndiRes external jndi resource
+     */
+    public void installExternalJndiResource(org.glassfish.resources.beans.ExternalJndiResource extJndiRes, ResourceInfo resourceInfo) {
+
+        try {
+            // create the external JNDI factory, its initial context and
+            // pass them as references.
+            String factoryClass = extJndiRes.getFactoryClass();
+            String jndiLookupName = extJndiRes.getJndiLookupName();
+
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.log(Level.FINE, "installExternalJndiResources resourceName "
+                        + resourceInfo + " factoryClass " + factoryClass
+                        + " jndiLookupName = " + jndiLookupName);
+            }
+
+
+            Object factory = ResourceUtil.loadObject(factoryClass);
+            if (factory == null) {
+                _logger.log(Level.WARNING, "jndi.factory_load_error", factoryClass);
+                return;
+
+            } else if (!(factory instanceof javax.naming.spi.InitialContextFactory)) {
+                _logger.log(Level.WARNING, "jndi.factory_class_unexpected", factoryClass);
+                return;
+            }
+
+            // Get properties to create the initial naming context
+            // for the target JNDI factory
+            Hashtable env = new Hashtable();
+            for (Iterator props = extJndiRes.getProperties().iterator();
+                 props.hasNext(); ) {
+
+                ResourceProperty prop = (ResourceProperty) props.next();
+                env.put(prop.getName(), prop.getValue());
+            }
+
+            Context context = null;
+            try {
+                context =
+                        ((InitialContextFactory) factory).getInitialContext(env);
+
+            } catch (NamingException ne) {
+                _logger.log(Level.SEVERE, "jndi.initial_context_error", factoryClass);
+                _logger.log(Level.SEVERE, "jndi.initial_context_error_excp", ne.getMessage());
+            }
+
+            if (context == null) {
+                _logger.log(Level.SEVERE, "jndi.factory_create_error", factoryClass);
+                return;
+            }
+
+            // Bind a Reference to the proxy object factory; set the
+            // initial context factory.
+            //JndiProxyObjectFactory.setInitialContext(bindName, context);
+
+            Reference ref = new Reference(extJndiRes.getResType(),
+                    "org.glassfish.resources.naming.JndiProxyObjectFactory",
+                    null);
+
+            // unique JNDI name within server runtime
+            ref.add(new SerializableObjectRefAddr("resourceInfo", resourceInfo));
+
+            // target JNDI name
+            ref.add(new StringRefAddr("jndiLookupName", jndiLookupName));
+
+            // target JNDI factory class
+            ref.add(new StringRefAddr("jndiFactoryClass", factoryClass));
+
+            // add Context info as a reference address
+            ref.add(new ProxyRefAddr(extJndiRes.getResourceInfo().getName(), env));
+
+            // Publish the reference
+            namingService.publishObject(resourceInfo, ref, true);
+
+        } catch (Exception ex) {
+            _logger.log(Level.SEVERE, "customrsrc.create_ref_error", resourceInfo);
+            _logger.log(Level.SEVERE, "customrsrc.create_ref_error_excp", ex);
+
+        }
+    }
+
+    /**
+     * Un-installs the external jndi resource.
+     *
+     * @param resource external jndi resource
+     */
+    public void uninstallExternalJndiResource(JavaEEResource resource, ResourceInfo resourceInfo) {
+
+        // removes the jndi context from the factory cache
+        //String bindName = resource.getResourceInfo().getName();
+        JndiProxyObjectFactory.removeInitialContext(resource.getResourceInfo());
+
+        // removes the resource from jndi naming
+        try {
+            namingService.unpublishObject(resourceInfo, resourceInfo.getName());
+            /* TODO V3 handle jms later
+            //START OF IASRI 4660565
+            if (((ExternalJndiResource)resource).isJMSConnectionFactory()) {
+                nm.unpublishObject(IASJmsUtil.getXAConnectionFactoryName(resourceName));
+            }
+            //END OF IASRI 4660565
+            */
+        } catch (javax.naming.NamingException e) {
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.log(Level.FINE,
+                        "Error while unpublishing resource: " + resourceInfo, e);
+            }
+        }
+    }
+
+
+    /**
+     * Returns a new instance of j2ee external jndi resource from the given
+     * config bean.
+     * <p/>
+     * This method gets called from the external resource
+     * deployer to convert external-jndi-resource config bean into
+     * external-jndi  j2ee resource.
+     *
+     * @param rbean external-jndi-resource config bean
+     * @return a new instance of j2ee external jndi resource
+     */
+    public static org.glassfish.resources.api.JavaEEResource toExternalJndiJavaEEResource(
+            ExternalJndiResource rbean, ResourceInfo resourceInfo) {
+
+        org.glassfish.resources.beans.ExternalJndiResource jr = new org.glassfish.resources.beans.ExternalJndiResource(resourceInfo);
+
+        //jr.setDescription( rbean.getDescription() ); // FIXME: getting error
+
+        // sets the enable flag
+        jr.setEnabled(Boolean.valueOf(rbean.getEnabled()));
+
+        // sets the jndi look up name
+        jr.setJndiLookupName(rbean.getJndiLookupName());
+
+        // sets the resource type
+        jr.setResType(rbean.getResType());
+
+        // sets the factory class name
+        jr.setFactoryClass(rbean.getFactoryClass());
+
+        // sets the properties
+        List<Property> properties = rbean.getProperty();
+        if (properties != null) {
+            for (Property property : properties) {
+                ResourceProperty rp =
+                        new ResourcePropertyImpl(property.getName(), property.getValue());
+                jr.addProperty(rp);
+            }
+        }
+        return jr;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean canDeploy(boolean postApplicationDeployment, Collection<Resource> allResources, Resource resource) {
+        if (handles(resource)) {
+            if (!postApplicationDeployment) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void validatePreservedResource(Application oldApp, Application newApp, Resource resource,
+                                          Resources allResources)
+            throws ResourceConflictException {
+        //do nothing.
+    }
+}
diff --git a/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourceUtilities.java b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourceUtilities.java
new file mode 100644
index 0000000..5a8064d
--- /dev/null
+++ b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourceUtilities.java
@@ -0,0 +1,233 @@
+/*
+ * 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.resources.module;
+
+import com.sun.enterprise.config.serverbeans.Resources;
+import org.glassfish.resources.api.Resource;
+import com.sun.logging.LogDomains;
+import com.sun.enterprise.util.i18n.StringManager;
+import org.glassfish.resourcebase.resources.api.ResourceConflictException;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+import java.util.*;
+
+import static org.glassfish.resources.admin.cli.ResourceConstants.*;
+
+/** A class that holds utility/helper routines. Expected to contain static
+*  methods to perform utility operations.
+*
+* @since Appserver 9.0
+*/
+public class ResourceUtilities {
+
+    private final static Logger _logger = LogDomains.getLogger(ResourceUtilities.class, LogDomains.RSR_LOGGER);
+    private final static StringManager localStrings =
+            StringManager.getManager(ResourceUtilities.class);
+
+     private ResourceUtilities()/*disallowed*/ {
+   }
+
+   /**
+    * Checks if any of the Resource in the given set has a conflict with
+    * resource definitions in the domain.xml. A <b> conflict </b> is defined
+    * based on the type of the resource. For example, a JDBC Resource has "jndi-name"
+    * that is the identifying key where as for a JDBC Connection Pool, it is
+    * the "name" that must be unique.
+    * @param resSet a Set of Resource elements.
+    * @param resources instance of ConfigContext that you want to confirm this against. May not be null.
+    * @return a Set of Resource elements that contains conflicting elements from the given Set. This
+    * method does not create any Resource elements. It just references an element in conflict
+    * from a Set that is returned. If there are no conflicts, an empty Set is returned. This method
+    * never returns a null. If the given Set is null, an empty Set is returned.
+    */
+   public static Set<org.glassfish.resources.api.Resource> getResourceConfigConflicts(final Set<org.glassfish.resources.api.Resource> resSet,
+       final Resources resources) {
+       final Set<Resource> conflicts = new HashSet<Resource>();
+       if (resSet != null) {
+           for (final org.glassfish.resources.api.Resource res : resSet) {
+               boolean duplicate = hasDuplicate(resources, res);
+               if (duplicate) {
+                   conflicts.add(res);
+               }
+           }
+       }
+       return ( conflicts );
+   }
+
+    private static boolean hasDuplicate(Resources resources, Resource res) {
+        final String id = getIdToCompare(res);
+        return resources.getResourceByName(res.getClass(), id) != null;
+    }
+
+    private static String getIdToCompare(final Resource res) {
+       final HashMap attrs = res.getAttributes();
+       final String type = res.getType();
+       String id;
+       if (org.glassfish.resources.api.Resource.JDBC_CONNECTION_POOL.equals(type) ||
+           Resource.CONNECTOR_CONNECTION_POOL.equals(type)){
+          id = getNamedAttributeValue(attrs, CONNECTION_POOL_NAME);   // this should come from refactored stuff TBD
+       }
+       else if (org.glassfish.resources.api.Resource.CONNECTOR_SECURITY_MAP.equals(type)) {
+           id = getNamedAttributeValue(attrs, SECURITY_MAP_NAME);  // this should come from refactored stuff TBD
+       }
+       else if (org.glassfish.resources.api.Resource.RESOURCE_ADAPTER_CONFIG.equals(type)) {
+           id = getNamedAttributeValue(attrs, RESOURCE_ADAPTER_CONFIG_NAME);  // this should come from refactored stuff TBD
+       }
+       else if(org.glassfish.resources.api.Resource.CONNECTOR_WORK_SECURITY_MAP.equals(type)){
+           id = getNamedAttributeValue(attrs, WORK_SECURITY_MAP_NAME);
+       }
+       else {
+           //it is OK to assume that this Resource will one of the *RESOURCEs?
+           id = getNamedAttributeValue(attrs, JNDI_NAME); // this should come from refactored stuff TBD
+       }
+       return ( id );
+   }
+
+     private static String getNamedAttributeValue(final HashMap attributes, final String name) {
+         return (String)attributes.get(name);
+     }
+
+     /**
+      * Resolves all duplicates and conflicts within an archive and returns a set
+      * of resources that needs to be created for the archive being deployed. The
+      * deployment backend would then use these set of resources to check for
+      * conflicts with resources existing in domain.xml and then continue
+      * with deployment.
+      *
+      * All resource duplicates within an archive found are flagged with a
+      * WARNING and only one resource is added in the final <code>Resource</code>
+      * <code>Set</code> returned.
+      *
+      * We currently do not handle any resource conflicts found within the archive
+      * and the method throws an exception when this condition is detected.
+      *
+      * @param sunResList a list of <code>SunResourcesXML</code> corresponding to
+      * sun-resources.xml found within an archive.
+      *
+      * @return a Set of <code>Resource</code>s that have been resolved of
+      * duplicates and conflicts.
+      *
+      * @throws org.glassfish.resources.api.ResourceConflictException an exception is thrown when an archive is found to
+      * have two or more resources that conflict with each other.
+      */
+     public static Set<org.glassfish.resources.api.Resource> resolveResourceDuplicatesConflictsWithinArchive(
+             List<org.glassfish.resources.admin.cli.SunResourcesXML> sunResList) throws ResourceConflictException {
+         boolean conflictExist = false;
+         StringBuffer conflictingResources = new StringBuffer();
+         Set<org.glassfish.resources.api.Resource> resourceSet = new HashSet<org.glassfish.resources.api.Resource>();
+         Iterator<org.glassfish.resources.admin.cli.SunResourcesXML> sunResourcesXMLIter = sunResList.iterator();
+         while(sunResourcesXMLIter.hasNext()){
+             //get list of resources from one sun-resources.xml file
+             org.glassfish.resources.admin.cli.SunResourcesXML sunResXML = sunResourcesXMLIter.next();
+             List<org.glassfish.resources.api.Resource> resources = sunResXML.getResourcesList();
+             Iterator<org.glassfish.resources.api.Resource> resourcesIter = resources.iterator();
+             //for each resource mentioned
+             while(resourcesIter.hasNext()){
+                 org.glassfish.resources.api.Resource res = resourcesIter.next();
+                 Iterator<org.glassfish.resources.api.Resource> resSetIter = resourceSet.iterator();
+                 boolean addResource = true;
+                 //check if a duplicate has already been added
+                 while(resSetIter.hasNext()){
+                     Resource existingRes = resSetIter.next();
+                     if(existingRes.equals(res)){
+                         //duplicate within an archive
+                         addResource = false;
+                         _logger.warning(localStrings.getString("duplicate.resource.sun.resource.xml",
+                                 getIdToCompare(res), sunResXML.getXMLPath()));
+                         break;
+                     }
+                     //check if another existing resource conflicts with the
+                     //resource being added
+                     if(existingRes.isAConflict(res)){
+                         //conflict within an archive
+                         addResource = false;
+                         conflictingResources.append("\n");
+                         String message = localStrings.getString("conflict.resource.sun.resource.xml",
+                                 getIdToCompare(res), sunResXML.getXMLPath());
+                         conflictingResources.append(message);
+                         _logger.warning(message);
+                         if(_logger.isLoggable(Level.FINE))
+                             logAttributes(res);
+                     }
+                 }
+                 if(addResource)
+                     resourceSet.add(res);
+             }
+         }
+         if(conflictingResources.toString().length() > 0){
+             throw new ResourceConflictException(conflictingResources.toString());
+         }
+         return resourceSet;
+     }
+
+     /**
+      * Checks if any of the Resource in the given set has a conflict with
+      * resource definitions in the domain.xml. A <b> conflict </b> is defined
+      * based on the type of the resource. For example, a JDBC Resource has "jndi-name"
+      * that is the identifying key where as for a JDBC Connection Pool, it is
+      * the "name" that must be unique.
+      *
+      * @param resList a Set of Resource elements.
+      * @param resources all resources from domain.xml
+      *
+      * @throws org.glassfish.resources.api.ResourceConflictException an exception is thrown when an archive is found to
+      * have two or more resources that conflict with resources already present in domain.xml.
+      */
+     public static void getResourceConflictsWithDomainXML(final List<Resource> resList,
+             final Resources resources) throws ResourceConflictException {
+         if (resList != null) {
+             Iterator<org.glassfish.resources.api.Resource> iterRes = resList.iterator();
+             StringBuffer conflictingResources = new StringBuffer();
+             while (iterRes.hasNext()) {
+                 org.glassfish.resources.api.Resource res = iterRes.next();
+                 final String id = getIdToCompare(res);
+
+                 if (resources.getResourceByName(res.getClass(), id) != null) {
+                     conflictingResources.append("\n");
+                     String message = localStrings.getString("conflict.resource.with.domain.xml",
+                             getIdToCompare(res));
+                     conflictingResources.append(message);
+                     _logger.warning(message);
+                     if(_logger.isLoggable(Level.FINE))
+                         logAttributes(res);
+                 }
+             }
+             if(conflictingResources.toString().length() > 0){
+                 throw new ResourceConflictException(conflictingResources.toString());
+             }
+         }
+     }
+
+    private static void logAttributes(Resource res) {
+        StringBuffer message = new StringBuffer();
+        Set<Map.Entry> entries = res.getAttributes().entrySet();
+        Iterator<Map.Entry> entriesIter = entries.iterator();
+        while(entriesIter.hasNext()){
+            Map.Entry entry = entriesIter.next();
+            message.append(entry.getKey());
+            message.append("=");
+            message.append(entry.getValue());
+            message.append(" ");
+        }
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine(localStrings.getString("resource.attributes",
+                    message.toString()));
+        }
+    }
+}
diff --git a/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesApplication.java b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesApplication.java
new file mode 100644
index 0000000..9fa10f6
--- /dev/null
+++ b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesApplication.java
@@ -0,0 +1,110 @@
+/*
+ * 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.resources.module;
+
+import com.sun.enterprise.config.serverbeans.*;
+import com.sun.logging.LogDomains;
+import java.util.logging.Level;
+import org.glassfish.api.deployment.*;
+import org.glassfish.internal.data.ApplicationRegistry;
+import org.glassfish.resources.listener.ApplicationScopedResourcesManager;
+import org.jvnet.hk2.annotations.Service;
+
+import org.glassfish.hk2.api.PerLookup;
+
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+
+@Service
+@PerLookup
+public class ResourcesApplication implements ApplicationContainer{
+
+    private static final Logger _logger = LogDomains.getLogger(ResourcesApplication.class, LogDomains.RSR_LOGGER);
+    private String applicationName;
+
+    @Inject
+    private ApplicationRegistry appRegistry;
+
+    @Inject
+    private Applications applications;
+
+    private Resources resources ;
+
+    @Inject
+    private ApplicationScopedResourcesManager asrManager;
+    
+    @Inject
+    private ResourcesDeployer resourcesDeployer;
+
+    public ResourcesApplication(){
+    }
+
+    public void setApplicationName(String applicationName){
+        this.applicationName = applicationName;
+    }
+
+    public String getApplicationName(){
+        return applicationName;
+    }
+
+    public Object getDescriptor() {
+        //TODO return all resources-xml ?
+        return null;  
+    }
+
+    public boolean start(ApplicationContext startupContext) throws Exception {
+        DeploymentContext dc = (DeploymentContext)startupContext;
+        final DeployCommandParameters deployParams = dc.getCommandParameters(DeployCommandParameters.class);
+        //during app. deployment, create resources config and load resources
+        if(deployParams.origin == OpsParams.Origin.deploy || deployParams.origin == OpsParams.Origin.deploy_instance){
+            resourcesDeployer.deployResources(applicationName, true);
+        }else if (deployParams.origin == OpsParams.Origin.load ||
+                deployParams.origin == OpsParams.Origin.create_application_ref) {
+            //<application> and its <resources>, <modules> are already available.
+            //Deploy them.
+            
+            //during app. load (eg: server start or application/application-ref enable(), load resources
+            asrManager.deployResources(applicationName);
+        }
+        return true;
+    }
+
+    public boolean stop(ApplicationContext stopContext) {
+        asrManager.undeployResources(applicationName);
+        return true;
+    }
+
+    public boolean suspend() {
+        return true;
+    }
+
+    public boolean resume() throws Exception {
+        return true;
+    }
+
+    public ClassLoader getClassLoader() {
+        //TODO return loader
+        return null;
+    }
+    private void  debug(String message){
+        if(_logger.isLoggable(Level.FINEST)) {
+            _logger.finest("[ResourcesApplication] " + message);
+        }
+    }
+
+}
diff --git a/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesContainer.java b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesContainer.java
new file mode 100644
index 0000000..39f3ca7
--- /dev/null
+++ b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesContainer.java
@@ -0,0 +1,71 @@
+/*
+ * 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.resources.module;
+
+import com.sun.logging.LogDomains;
+import org.glassfish.api.container.Container;
+import org.glassfish.api.deployment.Deployer;
+import org.glassfish.resourcebase.resources.api.ResourceConstants;
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.hk2.api.PreDestroy;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+@Service(name = "org.glassfish.resources.module.ResourcesContainer")
+public class ResourcesContainer implements Container, PostConstruct, PreDestroy {
+
+    private final static Logger _logger = LogDomains.getLogger(ResourcesContainer.class, LogDomains.RSR_LOGGER);
+
+    public void postConstruct() {
+        logFine("postConstruct of ConnectorContainer");
+    }
+
+    public void preDestroy() {
+        logFine("preDestroy of ConnectorContainer");
+    }
+
+    /**
+     * Returns the Deployer implementation capable of deploying applications to this
+     * container.
+     *
+     * @return the Deployer implementation
+     */
+    public Class<? extends Deployer> getDeployer() {
+        return ResourcesDeployer.class;
+    }
+
+    /**
+     * Returns a human readable name for this container, this name is not used for
+     * identifying the container but can be used to display messages belonging to
+     * the container.
+     *
+     * @return a human readable name for this container.
+     */
+    public String getName() {
+        return ResourceConstants.GF_RESOURCES_MODULE;
+    }
+
+    public void logFine(String message) {
+        if(_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, message);
+        }
+    }
+
+}
diff --git a/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesDeployer.java b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesDeployer.java
new file mode 100644
index 0000000..d6c49b8
--- /dev/null
+++ b/appserver/resources/resources-runtime/src/main/java/org/glassfish/resources/module/ResourcesDeployer.java
@@ -0,0 +1,1010 @@
+/*
+ * Copyright (c) 2010, 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.resources.module;
+
+import com.sun.enterprise.config.serverbeans.*;
+import com.sun.enterprise.config.serverbeans.Resource;
+import com.sun.enterprise.deployment.util.DOLUtils;
+import com.sun.logging.LogDomains;
+import org.glassfish.api.deployment.DeployCommandParameters;
+import org.glassfish.api.deployment.DeploymentContext;
+import org.glassfish.api.deployment.OpsParams;
+import org.glassfish.api.deployment.UndeployCommandParameters;
+import org.glassfish.api.deployment.archive.ReadableArchive;
+import org.glassfish.api.event.*;
+import org.glassfish.deployment.common.DeploymentException;
+import org.glassfish.deployment.common.DeploymentProperties;
+import org.glassfish.deployment.common.DeploymentUtils;
+import org.glassfish.internal.api.ServerContext;
+import org.glassfish.internal.data.ApplicationInfo;
+import org.glassfish.internal.data.ApplicationRegistry;
+import org.glassfish.internal.deployment.Deployment;
+import org.glassfish.javaee.core.deployment.JavaEEDeployer;
+import org.glassfish.resources.admin.cli.ResourceManager;
+import org.glassfish.resources.admin.cli.ResourcesXMLParser;
+import org.glassfish.resources.admin.cli.SunResourcesXML;
+import org.glassfish.resources.api.*;
+import org.glassfish.resourcebase.resources.util.ResourceManagerFactory;
+import org.glassfish.resourcebase.resources.api.ResourceDeployer;
+import org.glassfish.resources.util.ResourceUtil;
+import org.glassfish.resourcebase.resources.api.ResourcesBinder;
+import org.glassfish.resourcebase.resources.api.ResourceConflictException;
+import org.glassfish.resourcebase.resources.api.ResourceConstants;
+import org.glassfish.resourcebase.resources.api.ResourceInfo;
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.hk2.api.PreDestroy;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.jvnet.hk2.config.*;
+
+import org.glassfish.api.event.EventListener;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.resource.ResourceException;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static org.glassfish.resources.admin.cli.ResourceConstants.*;
+import static org.glassfish.resources.api.Resource.*;
+import static org.glassfish.resourcebase.resources.api.ResourceConstants.*;
+
+/**
+ * ResourcesDeployer to handle "glassfish-resources.xml(s)" bundled in the application.
+ *
+ * @author Jagadish Ramu
+ */
+@Service
+public class ResourcesDeployer extends JavaEEDeployer<ResourcesContainer, ResourcesApplication>
+        implements PostConstruct, PreDestroy, EventListener {
+    private final org.glassfish.resources.admin.cli.ResourceFactory resourceFactory;
+
+    @Inject
+    private Domain domain;
+
+    @Inject
+    private ServerContext context;
+    
+    @Inject
+    private Provider<ResourcesApplication> resourcesApplicationProvider;
+
+    private final ApplicationRegistry appRegistry;
+
+    private final Provider<ResourceManagerFactory> resourceManagerFactoryProvider;
+
+    private final ResourcesBinder resourcesBinder;
+
+    @Inject
+    private ConfigSupport configSupport;
+
+    @Inject
+    private Events events;
+
+    @Inject
+    private ServiceLocator locator; 
+
+    private final Applications applications;
+
+    private static Map<String, Application> preservedApps = new HashMap<String, Application>();
+
+    private final static Logger _logger = LogDomains.getLogger(ResourcesDeployer.class, LogDomains.RSR_LOGGER);
+
+    private static final String RESOURCES_XML_META_INF = "META-INF/glassfish-resources.xml";
+    private static final String RESOURCES_XML_WEB_INF = "WEB-INF/glassfish-resources.xml";
+
+    @Inject
+    public ResourcesDeployer(org.glassfish.resources.admin.cli.ResourceFactory resourceFactoryParam,
+            ApplicationRegistry appRegistryParam,
+            Provider<ResourceManagerFactory> resourceManagerFactoryProviderParam,
+            ResourcesBinder resourcesBinderParam,
+            Applications applicationsParam) {
+        resourceFactory = resourceFactoryParam;
+        appRegistry = appRegistryParam;
+        resourceManagerFactoryProvider = resourceManagerFactoryProviderParam;
+        resourcesBinder = resourcesBinderParam;
+        applications = applicationsParam;
+    }
+
+    public void postConstruct() {
+        events.register(this);
+    }
+
+    public void preDestroy(){
+        events.unregister(this);
+    }
+
+    /**
+     * Loads a previously prepared application in its execution environment and
+     * return a ContractProvider instance that will identify this environment in
+     * future communications with the application's container runtime.
+     *
+     * @param container in which the application will reside
+     * @param context   of the deployment
+     * @return an ApplicationContainer instance identifying the running application
+     */
+    @Override
+    public ResourcesApplication load(ResourcesContainer container, DeploymentContext context) {
+        super.load(container, context);
+        debug("App-Scoped-Resources ResourcesDeployer.load()");
+        ResourcesApplication application = resourcesApplicationProvider.get();
+        application.setApplicationName(getAppNameFromDeployCmdParams(context));
+        return application;
+    }
+
+    public void unload(ResourcesApplication appContainer, DeploymentContext context) {
+        //TODO unregistering resources, removing resources configuration.
+        debug("Resources-Deployer :unload() called");
+    }
+
+    /**
+     * Retrieve connector and non-connector resources from the archive.
+     *
+     * @param archive Archieve from which the resources to be retrieved.
+     * @param appName Name of the application
+     * @param connectorResources Connector resources will be added to this list.
+     * @param nonConnectorResources Non connector resources will be added to this list.
+     * @param resourceXmlParsers Resource xml parsers corresponding to both connector and non connector resources will be stored in this.
+     */
+    public void getResources(ReadableArchive archive, String appName,
+                                             List<org.glassfish.resources.api.Resource> connectorResources,
+                                             List<org.glassfish.resources.api.Resource> nonConnectorResources,
+                                             Map<org.glassfish.resources.api.Resource, ResourcesXMLParser> resourceXmlParsers) {
+        try {
+            if (ResourceUtil.hasResourcesXML(archive, locator)) {
+                Map<String, Map<String, List>> appScopedResources = new HashMap<String, Map<String, List>>();
+                Map<String, String> fileNames = new HashMap<String, String>();
+                //using appName as it is possible that "deploy --name=APPNAME" will
+                //be different than the archive name.
+                retrieveAllResourcesXMLs(fileNames, archive, appName);
+
+                for (Map.Entry<String, String> entry : fileNames.entrySet()) {
+                    String moduleName = entry.getKey();
+                    String fileName = entry.getValue();
+                    debug("GlassFish Resources XML : " + fileName);
+
+                    moduleName = org.glassfish.resourcebase.resources.util.ResourceUtil.getActualModuleNameWithExtension(moduleName);
+                    String scope;
+                    if (appName.equals(moduleName)) {
+                        scope = JAVA_APP_SCOPE_PREFIX;
+                    } else {
+                        scope = JAVA_MODULE_SCOPE_PREFIX;
+                    }
+
+                    File file = new File(fileName);
+                    ResourcesXMLParser parser = new ResourcesXMLParser(file, scope);
+
+                    validateResourcesXML(file, parser);
+
+                    List<org.glassfish.resources.api.Resource> resources = parser.getResourcesList();
+
+                    if (nonConnectorResources != null) {
+                        nonConnectorResources.addAll(ResourcesXMLParser.
+                                getNonConnectorResourcesList(resources, false, true));
+                    }
+
+                    if (connectorResources != null) {
+                        connectorResources.addAll(ResourcesXMLParser.
+                                getConnectorResourcesList(resources, false, true));
+                    }
+
+                    if (resourceXmlParsers != null) {
+                        for (org.glassfish.resources.api.Resource res : resources) {
+                            resourceXmlParsers.put(res, parser);
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            // only DeploymentExceptions are propagated and result in deployment failure
+            // in the event notification infrastructure
+            throw new DeploymentException("Failue while processing glassfish-resources.xml(s) in the archive ", e);
+        }
+    }
+    
+    private void processArchive(DeploymentContext dc) {
+
+        try {
+            ReadableArchive archive = dc.getSource();
+
+            if (ResourceUtil.hasResourcesXML(archive, locator)) {
+
+                Map<String,Map<String, List>> appScopedResources = new HashMap<String,Map<String,List>>();
+                Map<String, List<String>> jndiNames = new HashMap<String, List<String>>();
+                List<Map.Entry<String, String>> raNames = new ArrayList<>();
+                Map<String, String> fileNames = new HashMap<String, String>();
+
+                String appName = getAppNameFromDeployCmdParams(dc);
+                //using appName as it is possible that "deploy --name=APPNAME" will
+                //be different than the archive name.
+                retrieveAllResourcesXMLs(fileNames, archive, appName);
+
+                for (Map.Entry<String, String> entry: fileNames.entrySet()) {
+                    String moduleName = entry.getKey();
+                    String fileName = entry.getValue();
+                    debug("Sun Resources XML : " + fileName);
+
+                    moduleName = org.glassfish.resourcebase.resources.util.ResourceUtil.getActualModuleNameWithExtension(moduleName);
+                    String scope ;
+                    if(appName.equals(moduleName)){
+                        scope = JAVA_APP_SCOPE_PREFIX;
+                    }else{
+                        scope = JAVA_MODULE_SCOPE_PREFIX;
+                    }
+
+                    File file = new File(fileName);
+                    ResourcesXMLParser parser = new ResourcesXMLParser(file, scope);
+
+                    validateResourcesXML(file, parser);
+
+                    List list = parser.getResourcesList();
+
+                    Map<String, List> resourcesList = new HashMap<String, List>();
+                    List<String> jndiNamesList = new ArrayList<String>();
+                    List<org.glassfish.resources.api.Resource> nonConnectorResources =
+                            ResourcesXMLParser.getNonConnectorResourcesList(list, false, true);
+                    resourcesList.put(NON_CONNECTOR_RESOURCES, nonConnectorResources);
+                    for (org.glassfish.resources.api.Resource resource : nonConnectorResources) {
+                        String jndiName = extractJNDIName(resource);
+                        if (hasRAName(resource)) {
+                            raNames.add(new AbstractMap.SimpleEntry<>(extractRAName(resource), resource.getType()));
+                        }
+                        if (jndiName != null) {
+                            jndiNamesList.add(jndiName);
+                        }
+                    }
+
+                    List<org.glassfish.resources.api.Resource> connectorResources =
+                            ResourcesXMLParser.getConnectorResourcesList(list, false, true);
+                    resourcesList.put(CONNECTOR_RESOURCES, connectorResources);
+                    for (org.glassfish.resources.api.Resource resource : connectorResources) {
+                        String jndiName = extractJNDIName(resource);
+                        if (hasRAName(resource)) {
+                            raNames.add(new AbstractMap.SimpleEntry<>(extractRAName(resource), resource.getType()));
+                        }
+                        if (jndiName != null) {
+                            jndiNamesList.add(jndiName);
+                        }
+                    }
+
+                    jndiNames.put(moduleName, jndiNamesList);
+                    appScopedResources.put(moduleName, resourcesList);
+                }
+                dc.addTransientAppMetaData(APP_SCOPED_RESOURCES_JNDI_NAMES, jndiNames);
+                dc.addTransientAppMetaData(APP_SCOPED_RESOURCES_RA_NAMES, raNames);
+                dc.addTransientAppMetaData(APP_SCOPED_RESOURCES_MAP, appScopedResources);
+                ApplicationInfo appInfo = appRegistry.get(appName);
+                if(appInfo != null){
+                    Application app = dc.getTransientAppMetaData(ServerTags.APPLICATION, Application.class);
+                    appInfo.addTransientAppMetaData(ServerTags.APPLICATION, app);
+                }
+            }
+        } catch (Exception e) {
+            // only DeploymentExceptions are propagated and result in deployment failure
+            // in the event notification infrastructure
+            throw new DeploymentException("Failue while processing glassfish-resources.xml(s) in the archive ", e);
+        }
+    }
+
+    /**
+     * Extract the JNDI name from the resource. Collecting for resource valitation.
+     *
+     * @param resource
+     * @return jndi name if present, null otherwise
+     */
+    private String extractJNDIName(org.glassfish.resources.api.Resource resource) {
+        HashMap attrs = resource.getAttributes();
+        return (String) attrs.get(JNDI_NAME);
+    }
+
+    private boolean hasRAName(org.glassfish.resources.api.Resource resource) {
+        return resource.getType().equals(ADMIN_OBJECT_RESOURCE) ||
+                resource.getType().equals(CONNECTOR_CONNECTION_POOL) ||
+                resource.getType().equals(RESOURCE_ADAPTER_CONFIG) ||
+                resource.getType().equals(CONNECTOR_WORK_SECURITY_MAP);
+    }
+
+    /**
+     * Extract the RA name for a connector resource. Collecting for resource validation.
+     *
+     * @param resource
+     * @return resource adapter name
+     */
+    private String extractRAName(org.glassfish.resources.api.Resource resource) {
+        if (resource.getType().equals(ADMIN_OBJECT_RESOURCE))
+            return (String)resource.getAttributes().get(RES_ADAPTER);
+        else
+            return (String)resource.getAttributes().get(RES_ADAPTER_NAME);
+    }
+
+    private static void validateResourcesXML(File file, ResourcesXMLParser parser) throws ResourceConflictException {
+        String filePath = file.getPath();
+        SunResourcesXML sunResourcesXML = new SunResourcesXML(filePath, parser.getResourcesList());
+        List<SunResourcesXML> resourcesXMLList = new ArrayList<SunResourcesXML>();
+        resourcesXMLList.add(sunResourcesXML);
+        ResourceUtilities.resolveResourceDuplicatesConflictsWithinArchive(resourcesXMLList);
+    }
+
+    /**
+     * retain old resource configuration for the new archive being deployed.
+     * @param dc DeploymentContext
+     * @param allResources all resources (app scoped, module scoped) of old application
+     * @throws Exception when unable to retain old resource configuration.
+     */
+    public void retainResourceConfig(DeploymentContext dc, Map<String, Resources> allResources) throws Exception {
+        String appName = getAppNameFromDeployCmdParams(dc);
+        Application application = dc.getTransientAppMetaData(ServerTags.APPLICATION, Application.class);
+        Resources appScopedResources = allResources.get(appName);
+
+        if(appScopedResources != null){
+            application.setResources(appScopedResources);
+        }
+
+        if(DeploymentUtils.isArchiveOfType(dc.getSource(), DOLUtils.earType(), locator)){
+            List<Module> modules = application.getModule();
+            if(modules != null){
+                for(Module module : modules){
+                    Resources moduleScopedResources = allResources.get(module.getName());
+                    if(moduleScopedResources != null){
+                        module.setResources(moduleScopedResources);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * During "load()" event (eg: app/app-ref enable, server start),
+     * populate resource-config in app-info so that it can be used for
+     * constructing connector-classloader for the application.
+     * @param dc DeploymentContext
+     */
+    public void populateResourceConfigInAppInfo(DeploymentContext dc){
+        String appName = getAppNameFromDeployCmdParams(dc);
+        Application application = applications.getApplication(appName);
+        ApplicationInfo appInfo = appRegistry.get(appName);
+        if(application != null && appInfo != null){
+            Resources appScopedResources = application.getResources();
+            if(appScopedResources != null){
+                appInfo.addTransientAppMetaData(ServerTags.APPLICATION, application);
+                appInfo.addTransientAppMetaData(application.getName()+"-resources", appScopedResources);
+            }
+
+            List<Module> modules = application.getModule();
+            if(modules != null){
+                for(Module module : modules){
+                    Resources moduleScopedResources = module.getResources();
+                    if(moduleScopedResources != null){
+                        appInfo.addTransientAppMetaData(module.getName()+"-resources", moduleScopedResources);
+                    }
+                }
+            }
+        }
+    }
+
+    public void createResources(DeploymentContext dc, boolean embedded, boolean deployResources) throws ResourceException {
+        String appName = getAppNameFromDeployCmdParams(dc);
+        Application app = dc.getTransientAppMetaData(ServerTags.APPLICATION, Application.class);
+        Map<String, Map<String, List>> resourcesList =
+                (Map<String, Map<String, List>>)dc.getTransientAppMetadata().get(APP_SCOPED_RESOURCES_MAP);
+
+        if (resourcesList != null) {
+            Map<String, List> appLevelResources = resourcesList.get(appName);
+            if (appLevelResources != null) {
+                List<org.glassfish.resources.api.Resource> connectorResources =
+                        appLevelResources.get(CONNECTOR_RESOURCES);
+
+                createAppScopedResources(app, connectorResources, dc, embedded);
+
+                List<org.glassfish.resources.api.Resource> nonConnectorResources =
+                        appLevelResources.get(NON_CONNECTOR_RESOURCES);
+
+                createAppScopedResources(app, nonConnectorResources, dc, embedded);
+
+            }
+            List<Module> modules = app.getModule();
+            if (modules != null) {
+                for (Module module : modules) {
+                    String actualModuleName = org.glassfish.resourcebase.resources.util.ResourceUtil.getActualModuleNameWithExtension(module.getName());
+                    //create resources for modules, ignore standalone applications where
+                    //module name will be the same as app name
+                    if(!appName.equals(actualModuleName)){
+                        Map<String, List> moduleResources = resourcesList.get(actualModuleName);
+                        if (moduleResources != null) {
+                            List<org.glassfish.resources.api.Resource> connectorResources =
+                                    moduleResources.get(CONNECTOR_RESOURCES);
+                            createModuleScopedResources(app, module, connectorResources, dc, embedded);
+
+                            List<org.glassfish.resources.api.Resource> nonConnectorResources =
+                                    moduleResources.get(NON_CONNECTOR_RESOURCES);
+                            createModuleScopedResources(app, module, nonConnectorResources, dc, embedded);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private Collection<Resource>
+    createConfig(Resources resources, Collection<org.glassfish.resources.api.Resource> resourcesToRegister,
+                 boolean embedded)
+    throws ResourceException {
+        List<Resource> resourceConfigs =
+                new ArrayList<Resource>();
+        for (org.glassfish.resources.api.Resource resource : resourcesToRegister) {
+            final HashMap attrList = resource.getAttributes();
+            final Properties props = resource.getProperties();
+            String desc = resource.getDescription();
+            if (desc != null) {
+                attrList.put("description", desc);
+            }
+
+            try {
+                final ResourceManager rm = resourceFactory.getResourceManager(resource);
+                if(embedded && isEmbeddedResource(resource, resourcesToRegister)){
+                    Resource configBeanResource =
+                            rm.createConfigBean(resources, attrList, props, false);
+                    resources.getResources().add(configBeanResource);
+                    resourceConfigs.add(configBeanResource);
+                }else if(!embedded && !isEmbeddedResource(resource, resourcesToRegister)){
+                    com.sun.enterprise.config.serverbeans.Resource configBeanResource =
+                            rm.createConfigBean(resources, attrList, props, true);
+                    resources.getResources().add(configBeanResource);
+                    resourceConfigs.add(configBeanResource);
+                }
+            } catch (Exception e) {
+                throw new ResourceException(e);
+            }
+        }
+        return resourceConfigs;
+    }
+
+    private static boolean isConnectorResource(org.glassfish.resources.api.Resource resource){
+        if(resource.getType().equals(ADMIN_OBJECT_RESOURCE) ||
+           resource.getType().equals(CONNECTOR_CONNECTION_POOL) ||
+                resource.getType().equals(CONNECTOR_RESOURCE) ||
+                resource.getType().equals(RESOURCE_ADAPTER_CONFIG) ||
+                resource.getType().equals(CONNECTOR_WORK_SECURITY_MAP)){
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    private static boolean isEmbeddedResource(org.glassfish.resources.api.Resource resource,
+                                              Collection<org.glassfish.resources.api.Resource> resources){
+        boolean result = false;
+        if(isConnectorResource(resource)){
+            String attributeName = null;
+            if(resource.getType().equals(ADMIN_OBJECT_RESOURCE)){
+                attributeName = RES_ADAPTER;
+            } else if(resource.getType().equals(CONNECTOR_CONNECTION_POOL)){
+                attributeName = RES_ADAPTER_NAME;
+            } else if(resource.getType().equals(CONNECTOR_RESOURCE)){
+                String poolName = (String)resource.getAttributes().get(POOL_NAME);
+                if(poolName != null){
+                    org.glassfish.resources.api.Resource poolResource = getPoolResource(poolName, resources);
+                    //point to poolResource
+                    resource = poolResource;
+                    attributeName = RES_ADAPTER_NAME;
+                }
+            }/* else if(resource.getType().equals(org.glassfish.resources.api.Resource.RESOURCE_ADAPTER_CONFIG)){
+                attributeName = ResourceConstants.RES_ADAPTER_NAME;
+            } */else if(resource.getType().equals(CONNECTOR_WORK_SECURITY_MAP)){
+                attributeName = RES_ADAPTER_NAME;
+            }
+            if(attributeName != null && resource != null){
+                result = isEmbeddedRar(resource, attributeName);
+            }
+        }
+        return result;
+    }
+
+    private static org.glassfish.resources.api.Resource getPoolResource(
+            String poolName, Collection<org.glassfish.resources.api.Resource> resources){
+        org.glassfish.resources.api.Resource result = null;
+        for(org.glassfish.resources.api.Resource resource : resources){
+            if(resource.getType().equals(CONNECTOR_CONNECTION_POOL)){
+                String cpName = (String)resource.getAttributes().get(CONNECTION_POOL_NAME);
+                if(poolName.equals(cpName)){
+                    result = resource;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    private static boolean isEmbeddedRar(org.glassfish.resources.api.Resource resource, String attributeName) {
+        boolean result = false;
+        String raName = (String)resource.getAttributes().get(attributeName);
+        if(raName != null && raName.contains(ResourceConstants.EMBEDDEDRAR_NAME_DELIMITER)){
+            result = true;
+        }
+        return result;
+    }
+
+
+    private void createAppScopedResources(Application app, List<org.glassfish.resources.api.Resource> resources,
+                                                 DeploymentContext dc, boolean embedded)
+            throws ResourceException {
+        try {
+            if (resources != null) {
+                Application application = dc.getTransientAppMetaData(ServerTags.APPLICATION, Application.class);
+                Resources asc = dc.getTransientAppMetaData(APP_META_DATA_RESOURCES, Resources.class);
+                if (asc == null) {
+                    asc = application.createChild(Resources.class);
+                    application.setResources(asc);
+                    dc.addTransientAppMetaData(APP_META_DATA_RESOURCES, asc);
+                    ApplicationInfo appInfo = appRegistry.get(app.getName());
+                    if(appInfo != null){
+                        appInfo.addTransientAppMetaData(app.getName()+"-resources", asc);
+                    }
+                }
+
+                createConfig(asc, resources, embedded);
+                String appName = app.getName();
+                preserveResources(asc, appName, appName);
+            }
+        } catch (Exception e) {
+            Object params[] = new Object[]{app.getName(), e};
+            _logger.log(Level.SEVERE, "gf.resources.app.scope.deployment.failure", params);
+            throw new ResourceException(e);
+        }
+    }
+
+    /**
+     * preserve the resources such that they can be undeployed during deployment failure.
+     * @param resources resources
+     * @param appName application-name
+     * @param moduleName module-name
+     */
+    private static void preserveResources(Resources resources, String appName, String moduleName) {
+        Map<String, Resources> allResources = ResourcesRegistry.getResources(appName);
+        if(allResources != null){
+            allResources.put(moduleName, resources);
+        }else{
+            allResources = new HashMap<String, Resources>();
+            allResources.put(moduleName, resources);
+            ResourcesRegistry.putResources(appName, allResources);
+        }
+    }
+                            
+    private void createModuleScopedResources(Application app, Module module,
+                                                    List<org.glassfish.resources.api.Resource> resources,
+                                                    DeploymentContext dc, boolean embedded)
+            throws ResourceException {
+        try {
+            if (resources != null) {
+                Resources msc = dc.getTransientAppMetaData(module.getName()+"-resources", Resources.class);
+                if (msc == null) {
+                    msc = module.createChild(Resources.class);
+                    module.setResources(msc);
+                    dc.addTransientAppMetaData(module.getName()+"-resources", msc);
+                    ApplicationInfo appInfo = appRegistry.get(app.getName());
+                    if(appInfo != null){
+                        appInfo.addTransientAppMetaData(module.getName()+"-resources", msc);
+                    }
+                }
+
+                createConfig(msc, resources, embedded);
+                preserveResources(msc, app.getName(), module.getName());
+            }
+        } catch (Exception e) {
+            Object params[] = new Object[]{module.getName(),app.getName(), e};
+            _logger.log(Level.SEVERE, "gf.resources.module.scope.deployment.failure", params);
+            throw new ResourceException(e);
+        }
+    }
+
+    public void  deployResourcesFromConfiguration(String appName, boolean embedded) throws Exception {
+        Application application = applications.getApplication(appName);
+        ApplicationInfo appInfo = appRegistry.get(appName);
+        if(application != null && appInfo != null){
+            Resources appScopedResources = application.getResources();
+            if(appScopedResources != null){
+                deployResources(appName, null, appScopedResources.getResources(), embedded);
+            }
+
+            List<Module> modules = application.getModule();
+            if(modules != null){
+                for(Module module : modules){
+                    Resources moduleScopedResources = module.getResources();
+                    String moduleName = module.getName();
+                    if(moduleScopedResources != null){
+                        deployResources(appName, moduleName, moduleScopedResources.getResources(), embedded);
+                    }
+                }
+            }
+        }
+    }
+
+    public void  deployResources(String applicationName, boolean postDeployPhase) throws Exception {
+        Map<String, Resources> allResources = ResourcesRegistry.getResources(applicationName);
+        if(allResources != null){
+            for(Map.Entry<String, Resources> entry : allResources.entrySet()){
+                String moduleName = entry.getKey();
+                Resources resources = entry.getValue();
+                if(applicationName.equals(moduleName)){
+                    deployResources(applicationName, null, resources.getResources(), postDeployPhase);
+                }else{
+                    deployResources(applicationName, moduleName, resources.getResources(), postDeployPhase);
+                }
+            }
+        }
+    }
+    public void deployResources(String applicationName, String moduleName,
+                                Collection<com.sun.enterprise.config.serverbeans.Resource> resources,
+                                boolean postDeployPhase) throws Exception {
+        for(Resource resource : resources){
+            if(resource instanceof BindableResource) {
+                BindableResource bindableResource = (BindableResource)resource;
+                ResourceInfo resourceInfo = new ResourceInfo(bindableResource.getJndiName(), applicationName, moduleName);
+                if(getResourceDeployer(bindableResource).canDeploy(postDeployPhase, resources, bindableResource)){
+                    resourcesBinder.deployResource(resourceInfo, bindableResource);
+                }
+            } else{
+                if(getResourceDeployer(resource).canDeploy(postDeployPhase, resources, resource)){
+                    getResourceDeployer(resource).deployResource(resource, applicationName, moduleName);
+                }
+            }
+        }
+    }
+
+    private static String getAppNameFromDeployCmdParams(DeploymentContext dc) {
+        final DeployCommandParameters commandParams = dc.getCommandParameters(DeployCommandParameters.class);
+        return commandParams.name();
+    }
+
+    public void retrieveAllResourcesXMLs(Map<String, String> fileNames, ReadableArchive archive,
+                                         String actualArchiveName) throws IOException {
+
+        if(DeploymentUtils.isArchiveOfType(archive, DOLUtils.earType(), locator)){
+            //Look for top-level META-INF/glassfish-resources.xml
+            if(archive.exists(RESOURCES_XML_META_INF)){
+                String archivePath = archive.getURI().getPath();
+                String fileName = archivePath + RESOURCES_XML_META_INF;
+                if(_logger.isLoggable(Level.FINEST)){
+                    _logger.finest("GlassFish-Resources Deployer - fileName : " + fileName +
+                            " - parent : " + archive.getName());
+                }
+                fileNames.put(actualArchiveName, fileName);
+            }
+
+            //Lok for sub-module level META-INF/glassfish-resources.xml and WEB-INF/glassfish-resources.xml
+            Enumeration<String> entries = archive.entries();
+            while(entries.hasMoreElements()){
+                String element = entries.nextElement();
+                if(element.endsWith(".jar") || element.endsWith(".war") || element.endsWith(".rar") ||
+                        element.endsWith("_jar") || element.endsWith("_war") || element.endsWith("_rar")){
+                    ReadableArchive subArchive = archive.getSubArchive(element);
+                    if(subArchive != null ){
+                        retrieveResourcesXMLFromArchive(fileNames, subArchive, subArchive.getName());
+                    }
+                }
+            }
+        }else{
+            //Look for standalone archive's META-INF/glassfish-resources.xml and WEB-INF/glassfish-resources.xml
+            retrieveResourcesXMLFromArchive(fileNames, archive, actualArchiveName);
+        }
+    }
+
+    private void retrieveResourcesXMLFromArchive(Map<String, String> fileNames, ReadableArchive archive,
+                                                 String actualArchiveName) {
+        if(ResourceUtil.hasResourcesXML(archive, locator)){
+            String archivePath = archive.getURI().getPath();
+            String fileName ;
+            if(DeploymentUtils.isArchiveOfType(archive, DOLUtils.warType(), locator)){
+                fileName = archivePath +  RESOURCES_XML_WEB_INF;
+            }else{
+                fileName = archivePath + RESOURCES_XML_META_INF;
+            }
+            if(_logger.isLoggable(Level.FINEST)){
+                _logger.finest("GlassFish-Resources Deployer - fileName : " + fileName +
+                        " - parent : " + archive.getName());
+            }
+
+            fileNames.put(actualArchiveName, fileName);
+        }
+    }
+
+    /**
+     * Given a <i>resource</i> instance, appropriate deployer will be provided
+     *
+     * @param resource resource instance
+     * @return ResourceDeployer
+     */
+    private ResourceDeployer getResourceDeployer(Object resource){
+        return resourceManagerFactoryProvider.get().getResourceDeployer(resource);
+    }
+
+    /**
+     * Event listener to listen to </code>application undeploy validation</code> and
+     * if <i>preserveResources</i> flag is set, cache the &lt;resources&gt;
+     * config for persisting it in domain.xml
+     */
+    public void event(Event event) {
+        if (event.is(Deployment.DEPLOYMENT_BEFORE_CLASSLOADER_CREATION)) {
+            DeploymentContext dc = (DeploymentContext) event.hook();
+            final DeployCommandParameters deployParams = dc.getCommandParameters(DeployCommandParameters.class);
+            processResources(dc, deployParams);
+        }else if(event.is(Deployment.UNDEPLOYMENT_VALIDATION)){
+            DeploymentContext dc = (DeploymentContext) event.hook();
+            final UndeployCommandParameters undeployCommandParameters =
+                    dc.getCommandParameters(UndeployCommandParameters.class);
+            preserveResources(dc, undeployCommandParameters);
+        }else if(Deployment.UNDEPLOYMENT_FAILURE.equals(event.type())){
+            DeploymentContext dc = (DeploymentContext) event.hook();
+            cleanupPreservedResources(dc, event);
+        }else if(Deployment.DEPLOYMENT_FAILURE.equals(event.type())){
+            DeploymentContext dc = (DeploymentContext) event.hook();
+            String appName = getAppNameFromDeployCmdParams(dc);
+            cleanupResources(appName, dc.getCommandParameters(DeployCommandParameters.class).origin);
+            //TODO ASR call this only when the flag is on ? --properties preserveAppScopedResources=true
+            cleanupPreservedResources(dc, event);
+        }else if(Deployment.DEPLOYMENT_SUCCESS.equals(event.type())){
+            ApplicationInfo applicationInfo = (ApplicationInfo) event.hook();
+            String appName = applicationInfo.getName();
+            ResourcesRegistry.remove(appName);
+        }
+    }
+
+    private void processResources(DeploymentContext dc, DeployCommandParameters deployParams) {
+        try{
+            if (deployParams.origin == OpsParams.Origin.deploy || deployParams.origin == OpsParams.Origin.deploy_instance
+                    /*|| (deployParams.origin == OpsParams.Origin.create_application_ref && env.isInstance())*/) {
+                Properties properties = deployParams.properties;
+                if(properties != null){
+                    //handle if "preserveAppScopedResources" property is set (during deploy --force=true or redeploy)
+                    String preserve = properties.getProperty(DeploymentProperties.PRESERVE_APP_SCOPED_RESOURCES);
+                    if (preserve != null && Boolean.valueOf(preserve)) {
+                        Boolean redeploy = false;
+                        redeploy = deployParams.force;
+
+                        if (redeploy) {
+                            String appName = getAppNameFromDeployCmdParams(dc);
+                            Map<String, Resources> allResources = ResourcesRegistry.remove(appName);
+                            Application oldApp = preservedApps.remove(appName);
+                            if (allResources != null && oldApp != null) {
+                                Application application = dc.getTransientAppMetaData(ServerTags.APPLICATION, Application.class);
+                                validatePreservedResources(allResources, oldApp, application);
+                                retainResourceConfig(dc, allResources);
+                            }
+                           return;
+                        }
+                    }
+                }
+                Application app = dc.getTransientAppMetaData(ServerTags.APPLICATION, Application.class);
+                String applicationName = getAppNameFromDeployCmdParams(dc);
+                if(app != null){
+                    //application is stored in transient meta data only during deployment.
+                    processArchive(dc);
+                    createResources(dc, false, true);
+                    createResources(dc, true, false);
+                    deployResources(applicationName, false);
+                }else{
+                    //application config is already present. Use the same.
+                    deployResourcesFromConfiguration(applicationName, false);
+                    populateResourceConfigInAppInfo(dc);
+                }
+            }else if(deployParams.origin == OpsParams.Origin.load){
+                //during load event (ie., app/app-ref enable or server start, resource configuration
+                //is present in domain.xml. Use the configuration.
+                populateResourceConfigInAppInfo(dc);
+            }
+        }catch(Exception e){
+            // only DeploymentExceptions are propagated and result in deployment failure
+            // in the event notification infrastructure
+            if(_logger.isLoggable(Level.FINEST)){
+                _logger.log(Level.FINEST, "Exception while processing archive of application" +
+                    " [ "+getAppNameFromDeployCmdParams(dc)+" ] for resources definitions : " + e.getCause());
+            }
+            throw new DeploymentException(e);
+        }
+    }
+
+    /**
+     * Validates the old resource configuration against new archive's modules.
+     * @param allResources all resources (app scoped, module scoped)
+     * @param oldApp Old Application config
+     * @param newApp New Applicatoin config
+     * @throws org.glassfish.resourcebase.resources.api.ResourceConflictException when it is not possible to map any of the resource(s) to
+     * new application/its modules
+     */
+    private void validatePreservedResources(Map<String, Resources> allResources, Application oldApp,
+                                               Application newApp) throws ResourceConflictException {
+
+        String appName = newApp.getName();
+        Resources appScopedResources = allResources.get(appName);
+        if (appScopedResources != null) {
+            for(Resource resource : appScopedResources.getResources()){
+                getResourceDeployer(resource).validatePreservedResource(oldApp, newApp, resource, appScopedResources);
+            }
+        }
+
+        List<Module> newModules = newApp.getModule();
+        for(Module newModule : newModules){
+            Module oldModule = oldApp.getModule(newModule.getName());
+            if(oldModule != null){
+                Resources oldModuleResources = oldModule.getResources();
+                if(oldModuleResources != null){
+                    for(Resource resource : oldModuleResources.getResources()){
+                        getResourceDeployer(resource).validatePreservedResource(oldApp, newApp, resource, oldModuleResources);
+                    }
+                }
+            }//else its a new module in the archive being redeployed.
+        }
+    }
+
+    /**
+     * clean up resources due to deployment failure.
+     * @param appName application-name
+     * @param deploymentPhase deployment-phase (deploy/load etc.,)
+     */
+    private void cleanupResources(String appName, OpsParams.Origin deploymentPhase){
+        try{
+            if (deploymentPhase == OpsParams.Origin.deploy || deploymentPhase == OpsParams.Origin.deploy_instance
+                    || deploymentPhase == OpsParams.Origin.create_application_ref) {
+                Map<String, Resources> allResources = ResourcesRegistry.remove(appName);
+                if(allResources != null){
+                    for(Map.Entry<String, Resources> entry : allResources.entrySet()){
+                        String moduleName = entry.getKey();
+                        Resources resources = entry.getValue();
+                        String actualModuleName = moduleName;
+                        //for app-scoped-resources, no module name is needed
+                        if(appName.equals(moduleName)){
+                            actualModuleName = null;
+                        }
+                        undeployResources(resources, appName, actualModuleName );
+                    }
+                }
+            }else if(deploymentPhase == OpsParams.Origin.load){
+
+                Application application = applications.getApplication(appName);
+                if(application != null){
+                    Resources appScopedResources = application.getResources();
+                    undeployResources(appScopedResources, appName, null);
+
+                    List<Module> modules = application.getModule();
+                    if(modules != null){
+                        for(Module module : modules){
+                            Resources moduleScopedResources = module.getResources();
+                            undeployResources(moduleScopedResources, appName, module.getName());
+                        }
+                    }
+                }
+            }
+        }catch(Exception e){
+            _logger.log(Level.WARNING, "Exception while cleaning-up resources during deployment failure", e);
+        }
+    }
+
+    private void undeployResources(Resources resources, String appName, String moduleName) {
+
+        if(resources != null){
+            for(Resource resource : resources.getResources()){
+                try{
+                    //delete pools after resources
+                    if(!(resource instanceof ResourcePool)){
+                        getResourceDeployer(resource).undeployResource(resource, appName, moduleName);
+                    }
+                }catch(Exception e){
+                    //ignore as this is cleanup
+                }
+            }
+            Collection<ResourcePool> pools= resources.getResources(ResourcePool.class);
+            for(ResourcePool pool : pools){
+                try{
+                    getResourceDeployer(pool).undeployResource(pool, appName, moduleName);
+                }catch(Exception e){
+                    //ignore as this is cleanup
+                }
+            }
+        }
+    }
+
+    private void cleanupPreservedResources(DeploymentContext dc, Event event) {
+        if (Deployment.DEPLOYMENT_FAILURE.equals(event.type())) {
+            final DeployCommandParameters deployCommandParameters =
+                    dc.getCommandParameters(DeployCommandParameters.class);
+            if (deployCommandParameters.origin == OpsParams.Origin.deploy ||
+                    deployCommandParameters.origin == OpsParams.Origin.deploy_instance || 
+                    deployCommandParameters.origin == OpsParams.Origin.create_application_ref) {
+                Properties properties = deployCommandParameters.properties;
+                String appName = deployCommandParameters.name();
+                cleanupPreservedResources(appName, properties);
+            }
+        } else if (Deployment.UNDEPLOYMENT_FAILURE.equals(event.type())) {
+            final UndeployCommandParameters undeployCommandParameters =
+                    dc.getCommandParameters(UndeployCommandParameters.class);
+            if (undeployCommandParameters.origin == OpsParams.Origin.undeploy) {
+                Properties properties = undeployCommandParameters.properties;
+                String appName = undeployCommandParameters.name();
+                cleanupPreservedResources(appName, properties);
+            }
+        }
+    }
+
+    private void cleanupPreservedResources(String appName, Properties properties) {
+        if(properties != null){
+            String preserve = properties.getProperty(DeploymentProperties.PRESERVE_APP_SCOPED_RESOURCES);
+            if(preserve != null && Boolean.valueOf(preserve)){
+                ResourcesRegistry.remove(appName);
+                preservedApps.remove(appName);
+            }
+        }
+    }
+
+
+    /**
+     * preserve the old application's resources so that they can be registered during deploy.
+     * @param dc DeploymentContext
+     * @param undeployCommandParameters undeploy command parameters
+     */
+    private void preserveResources(DeploymentContext dc, UndeployCommandParameters undeployCommandParameters) {
+        try{
+            if (undeployCommandParameters.origin == OpsParams.Origin.undeploy) {
+                Properties properties = undeployCommandParameters.properties;
+                if(properties != null){
+                    String preserve = properties.getProperty(DeploymentProperties.PRESERVE_APP_SCOPED_RESOURCES);
+                    if(preserve != null && Boolean.valueOf(preserve)){
+                        debug("Preserve app scoped resources enabled");
+                        final UndeployCommandParameters commandParams =
+                                dc.getCommandParameters(UndeployCommandParameters.class);
+                        String appName = commandParams.name();
+                        Application app = applications.getApplication(appName);
+                        preserveResources(app);
+                        //store application info (for module information ie., sniffer type)
+                        preservedApps.put(appName, app);
+                    }
+                }
+            }
+        }catch(Exception e){
+            // only DeploymentExceptions are propagated and result in deployment failure
+            // in the event notification infrastructure
+            throw new DeploymentException(e.getMessage(), e);
+        }
+    }
+
+    private void preserveResources(Application app) {
+        String appName = app.getName();
+        Map<String, Resources> allResources = new HashMap<String, Resources>();
+        Resources appScopedResources = app.getResources();
+        if(appScopedResources != null){
+            allResources.put(appName, appScopedResources);
+        }
+        List<Module> modules = app.getModule();
+        if(modules != null){
+            for(Module module : modules){
+                Resources moduleScopedResources = module.getResources();
+                if(moduleScopedResources != null){
+                    allResources.put(module.getName(), moduleScopedResources);
+                }
+            }
+        }
+        //store the resource-configuration
+        ResourcesRegistry.putResources(appName, allResources);
+    }
+
+    private static void debug(String message){
+        if(_logger.isLoggable(Level.FINEST)) {
+            _logger.finest("[ASR] ResourceDeployer : " + message);
+        }
+    }
+}