Author: dain Date: Thu Sep 16 23:18:27 2004 New Revision: 46235 Added: geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/J2EEAppClientModule.java geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/impl/J2EEAppClientModuleImpl.java Modified: geronimo/trunk/modules/client-builder/project.xml geronimo/trunk/modules/client-builder/src/java/org/apache/geronimo/client/builder/AppClientModuleBuilder.java geronimo/trunk/modules/client-builder/src/schema/geronimo-application-client.xsd geronimo/trunk/modules/deployment/src/java/org/apache/geronimo/deployment/DeploymentContext.java geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARConfigBuilder.java Log: A bit more progress on the app client container Modified: geronimo/trunk/modules/client-builder/project.xml ============================================================================== --- geronimo/trunk/modules/client-builder/project.xml (original) +++ geronimo/trunk/modules/client-builder/project.xml Thu Sep 16 23:18:27 2004 @@ -64,6 +64,12 @@ geronimo + geronimo-client + ${pom.currentVersion} + + + + geronimo geronimo-common ${pom.currentVersion} @@ -101,6 +107,12 @@ geronimo geronimo-naming + ${pom.currentVersion} + + + + geronimo + geronimo-system ${pom.currentVersion} Modified: geronimo/trunk/modules/client-builder/src/java/org/apache/geronimo/client/builder/AppClientModuleBuilder.java ============================================================================== --- geronimo/trunk/modules/client-builder/src/java/org/apache/geronimo/client/builder/AppClientModuleBuilder.java (original) +++ geronimo/trunk/modules/client-builder/src/java/org/apache/geronimo/client/builder/AppClientModuleBuilder.java Thu Sep 16 23:18:27 2004 @@ -16,6 +16,7 @@ */ package org.apache.geronimo.client.builder; +import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; @@ -35,21 +36,30 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.jar.Attributes; import java.util.zip.ZipEntry; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.transaction.UserTransaction; import org.apache.geronimo.common.xml.XmlBeansUtil; +import org.apache.geronimo.deployment.DeploymentContext; import org.apache.geronimo.deployment.DeploymentException; import org.apache.geronimo.deployment.service.GBeanHelper; import org.apache.geronimo.deployment.util.FileUtil; import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.GBeanInfoFactory; +import org.apache.geronimo.gbean.jmx.GBeanMBean; import org.apache.geronimo.j2ee.deployment.AppClientModule; import org.apache.geronimo.j2ee.deployment.EARContext; import org.apache.geronimo.j2ee.deployment.Module; import org.apache.geronimo.j2ee.deployment.ModuleBuilder; +import org.apache.geronimo.j2ee.management.impl.J2EEAppClientModuleImpl; +import org.apache.geronimo.kernel.Kernel; +import org.apache.geronimo.kernel.config.ConfigurationModuleType; +import org.apache.geronimo.kernel.repository.Repository; import org.apache.geronimo.naming.deployment.ENCConfigBuilder; import org.apache.geronimo.naming.java.ReadOnlyContext; import org.apache.geronimo.schema.SchemaConversionUtils; @@ -62,6 +72,8 @@ import org.apache.geronimo.xbeans.j2ee.ApplicationClientDocument; import org.apache.geronimo.xbeans.j2ee.ApplicationClientType; import org.apache.geronimo.xbeans.j2ee.EjbLocalRefType; +import org.apache.geronimo.system.main.CommandLineManifest; +import org.apache.geronimo.client.AppClientContainer; import org.apache.xmlbeans.SchemaTypeLoader; import org.apache.xmlbeans.XmlBeans; import org.apache.xmlbeans.XmlException; @@ -77,7 +89,15 @@ XmlBeans.typeLoaderForClassLoader(GerApplicationClientDocument.class.getClassLoader()) }); - private static final String PARENT_ID = "org/apache/geronimo/Server"; + private static final URI CONFIG_ID = URI.create("application-client"); + + private final Kernel kernel; + private final Repository repository; + + public AppClientModuleBuilder(Kernel kernel, Repository repository) { + this.kernel = kernel; + this.repository = repository; + } public XmlObject getDeploymentPlan(URL module) throws XmlException { try { @@ -142,7 +162,6 @@ GerApplicationClientType geronimoAppClient = geronimoAppClientDoc.addNewApplicationClient(); // set the parentId, configId and context root - geronimoAppClient.setParentId(PARENT_ID); if (null != appClient.getId()) { id = appClient.getId(); } @@ -281,35 +300,126 @@ public void addGBeans(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException { AppClientModule appClientModule = (AppClientModule) module; - - ApplicationClientType appClient = (ApplicationClientType) appClientModule.getSpecDD(); - GerApplicationClientType geronimoAppClient = (GerApplicationClientType) appClientModule.getVendorDD(); - - if (geronimoAppClient != null) { - GerGbeanType[] gbeans = geronimoAppClient.getGbeanArray(); - for (int i = 0; i < gbeans.length; i++) { - GBeanHelper.addGbean(new AppClientGBeanAdapter(gbeans[i]), cl, earContext); - } + URI appClientModuleLocation; + if (!appClientModule.getURI().equals(URI.create("/"))) { + appClientModuleLocation = appClientModule.getURI(); + } else { + appClientModuleLocation = URI.create("client.jar"); } - URI configID = earContext.getConfigID(); - + // add the app client module gbean Properties nameProps = new Properties(); nameProps.put("J2EEServer", earContext.getJ2EEServerName()); nameProps.put("J2EEApplication", earContext.getJ2EEApplicationName()); nameProps.put("j2eeType", "AppClientModule"); nameProps.put("name", appClientModule.getName()); - ObjectName name; + ObjectName appClientModuleObjectName; try { - name = new ObjectName(earContext.getJ2EEDomainName(), nameProps); + appClientModuleObjectName = new ObjectName(earContext.getJ2EEDomainName(), nameProps); } catch (MalformedObjectNameException e) { throw new DeploymentException("Unable to construct ObjectName", e); } - UserTransaction userTransaction = new UserTransactionImpl(); - ReadOnlyContext compContext = buildComponentContext(earContext, appClientModule, appClient, geronimoAppClient, userTransaction, cl); + GBeanMBean appClientModuleGBean = new GBeanMBean(J2EEAppClientModuleImpl.GBEAN_INFO, cl); + try { + appClientModuleGBean.setReferencePatterns("J2EEServer", Collections.singleton(earContext.getServerObjectName())); + if (!earContext.getJ2EEApplicationName().equals("null")) { + appClientModuleGBean.setReferencePatterns("J2EEApplication", Collections.singleton(earContext.getApplicationObjectName())); + } + appClientModuleGBean.setAttribute("deploymentDescriptor", null); + } catch (Exception e) { + throw new DeploymentException("Unable to initialize AppClientModule GBean", e); + } + earContext.addGBean(appClientModuleObjectName, appClientModuleGBean); + + // Create a new executable jar within the earcontext + ApplicationClientType appClient = (ApplicationClientType) appClientModule.getSpecDD(); + GerApplicationClientType geronimoAppClient = (GerApplicationClientType) appClientModule.getVendorDD(); + + JarOutputStream earOutputStream = earContext.getJos(); + try { + Manifest manifest = new Manifest(); + Attributes mainAttributes = manifest.getMainAttributes(); + mainAttributes.putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0"); + mainAttributes.putValue(Attributes.Name.MAIN_CLASS.toString(), "org.apache.geronimo.system.main.CommandLine"); + mainAttributes.putValue(CommandLineManifest.MAIN_GBEAN.toString(), appClientModuleObjectName.getCanonicalName()); + mainAttributes.putValue(CommandLineManifest.MAIN_METHOD.toString(), "deploy"); + mainAttributes.putValue(CommandLineManifest.CONFIGURATIONS.toString(), CONFIG_ID.toString()); + + earOutputStream.putNextEntry(new ZipEntry(appClientModuleLocation.getPath())); + JarOutputStream appClientOutputStream = new JarOutputStream(new BufferedOutputStream(earOutputStream), manifest); + + // this is an executable jar add the startup jar finder file + appClientOutputStream.putNextEntry(new ZipEntry("META-INF/startup-jar")); + appClientOutputStream.closeEntry(); + + DeploymentContext appClientDeploymentContext = null; + try { + appClientDeploymentContext = new DeploymentContext(earOutputStream, CONFIG_ID, ConfigurationModuleType.SERVICE, null, kernel); + } catch (MalformedObjectNameException e) { + throw new DeploymentException(e); + } + + // add the includes + GerDependencyType[] includes = geronimoAppClient.getIncludeArray(); + for (int i = 0; i < includes.length; i++) { + GerDependencyType include = includes[i]; + URI uri = getDependencyURI(include); + String name = uri.toString(); + int idx = name.lastIndexOf('/'); + if (idx != -1) { + name = name.substring(idx + 1); + } + URI path; + try { + path = new URI(name); + } catch (URISyntaxException e) { + throw new DeploymentException("Unable to generate path for include: " + uri, e); + } + try { + URL url = repository.getURL(uri); + appClientDeploymentContext.addInclude(path, url); + } catch (IOException e) { + throw new DeploymentException("Unable to add include: " + uri, e); + } + } + + // add the dependencies + GerDependencyType[] dependencies = geronimoAppClient.getDependencyArray(); + for (int i = 0; i < dependencies.length; i++) { + appClientDeploymentContext.addDependency(getDependencyURI(dependencies[i])); + } + + ClassLoader appClientClassLoader = appClientDeploymentContext.getClassLoader(repository); + + if (geronimoAppClient != null) { + GerGbeanType[] gbeans = geronimoAppClient.getGbeanArray(); + for (int i = 0; i < gbeans.length; i++) { + GBeanHelper.addGbean(new AppClientGBeanAdapter(gbeans[i]), appClientClassLoader, appClientDeploymentContext); + } + } + + UserTransaction userTransaction = new UserTransactionImpl(); + ReadOnlyContext componentContext = buildComponentContext(earContext, appClientModule, appClient, geronimoAppClient, userTransaction, appClientClassLoader); + GBeanMBean appClienContainerGBean = new GBeanMBean(AppClientContainer.GBEAN_INFO, cl); + try { + appClientModuleGBean.setAttribute("componentContext", componentContext); + } catch (Exception e) { + throw new DeploymentException("Unable to initialize AppClientModule GBean", e); + } + appClientDeploymentContext.addGBean(appClientModuleObjectName, appClienContainerGBean); + + appClientDeploymentContext.close(); + } catch (IOException e) { + throw new DeploymentException(e); + } finally { + try { + earOutputStream.closeEntry(); + } catch (IOException e) { + throw new DeploymentException(e); + } + } - // todo install the appclient gbean here } public SchemaTypeLoader getSchemaTypeLoader() { @@ -358,14 +468,6 @@ return refMap; } - - private static String getJ2eeStringValue(org.apache.geronimo.xbeans.j2ee.String string) { - if (string == null) { - return null; - } - return string.getStringValue(); - } - private URI getDependencyURI(GerDependencyType dep) throws DeploymentException { URI uri; if (dep.isSetUri()) { @@ -384,17 +486,6 @@ } } return uri; - } - - - private byte[] getBytes(InputStream is) throws IOException { - byte[] buffer = new byte[4096]; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int count; - while ((count = is.read(buffer)) > 0) { - baos.write(buffer, 0, count); - } - return baos.toByteArray(); } private static abstract class InstallCallback { Modified: geronimo/trunk/modules/client-builder/src/schema/geronimo-application-client.xsd ============================================================================== --- geronimo/trunk/modules/client-builder/src/schema/geronimo-application-client.xsd (original) +++ geronimo/trunk/modules/client-builder/src/schema/geronimo-application-client.xsd Thu Sep 16 23:18:27 2004 @@ -31,6 +31,7 @@ + Modified: geronimo/trunk/modules/deployment/src/java/org/apache/geronimo/deployment/DeploymentContext.java ============================================================================== --- geronimo/trunk/modules/deployment/src/java/org/apache/geronimo/deployment/DeploymentContext.java (original) +++ geronimo/trunk/modules/deployment/src/java/org/apache/geronimo/deployment/DeploymentContext.java Thu Sep 16 23:18:27 2004 @@ -131,7 +131,7 @@ return type; } - private JarOutputStream getJos() { + public JarOutputStream getJos() { if (outputStreams.isEmpty()) { throw new IllegalStateException(); } Modified: geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARConfigBuilder.java ============================================================================== --- geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARConfigBuilder.java (original) +++ geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARConfigBuilder.java Thu Sep 16 23:18:27 2004 @@ -16,6 +16,35 @@ */ package org.apache.geronimo.j2ee.deployment; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + import org.apache.geronimo.common.xml.XmlBeansUtil; import org.apache.geronimo.deployment.ConfigurationBuilder; import org.apache.geronimo.deployment.DeploymentException; @@ -41,30 +70,6 @@ import org.apache.xmlbeans.XmlBeans; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; - -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import java.io.*; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarOutputStream; -import java.util.jar.Manifest; -import java.util.zip.ZipEntry; /** * @version $Rev$ $Date$ Added: geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/J2EEAppClientModule.java ============================================================================== --- (empty file) +++ geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/J2EEAppClientModule.java Thu Sep 16 23:18:27 2004 @@ -0,0 +1,23 @@ +/** + * + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.j2ee.management; + +/** + * @version $Revision$ $Date$ + */ +public interface J2EEAppClientModule extends J2EEManagedObject { +} Added: geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/impl/J2EEAppClientModuleImpl.java ============================================================================== --- (empty file) +++ geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/impl/J2EEAppClientModuleImpl.java Thu Sep 16 23:18:27 2004 @@ -0,0 +1,117 @@ +/** + * + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.j2ee.management.impl; + +import java.util.Hashtable; +import javax.management.ObjectName; + +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoFactory; +import org.apache.geronimo.j2ee.management.J2EEApplication; +import org.apache.geronimo.j2ee.management.J2EEServer; +import org.apache.geronimo.kernel.jmx.JMXUtil; + +/** + * @version $Revision$ $Date$ + */ +public class J2EEAppClientModuleImpl { + private final String deploymentDescriptor; + private final J2EEServer server; + private final J2EEApplication application; + + public J2EEAppClientModuleImpl(String objectName, J2EEServer server, J2EEApplication application, String deploymentDescriptor) { + ObjectName myObjectName = JMXUtil.getObjectName(objectName); + verifyObjectName(myObjectName); + + this.server = server; + this.application = application; + this.deploymentDescriptor = deploymentDescriptor; + } + + /** + * ObjectName must match this pattern: + *

+ * domain:j2eeType=AppClientModule,name=MyName,J2EEServer=MyServer,J2EEApplication=MyApplication + */ + private void verifyObjectName(ObjectName objectName) { + if (objectName.isPattern()) { + throw new InvalidObjectNameException("ObjectName can not be a pattern", objectName); + } + Hashtable keyPropertyList = objectName.getKeyPropertyList(); + if (!"AppClientModule".equals(keyPropertyList.get("j2eeType"))) { + throw new InvalidObjectNameException("AppClientModule object name j2eeType property must be 'AppClientModule'", objectName); + } + if (!keyPropertyList.containsKey("name")) { + throw new InvalidObjectNameException("AppClientModule object must contain a name property", objectName); + } + if (!keyPropertyList.containsKey("J2EEServer")) { + throw new InvalidObjectNameException("AppClientModule object name must contain a J2EEServer property", objectName); + } + if (!keyPropertyList.containsKey("J2EEApplication")) { + throw new InvalidObjectNameException("AppClientModule object name must contain a J2EEApplication property", objectName); + } + if (keyPropertyList.size() != 4) { + throw new InvalidObjectNameException("AppClientModule object name can only have j2eeType, name, J2EEApplication, and J2EEServer properties", objectName); + } + } + + public String getDeploymentDescriptor() { + return deploymentDescriptor; + } + + public String getServer() { + return server.getObjectName(); + } + + public String getApplication() { + if (application == null) { + return null; + } + return application.getObjectName(); + } + + public String[] getJavaVMs() { + return server.getJavaVMs(); + } + + public static final GBeanInfo GBEAN_INFO; + + static { + GBeanInfoFactory infoFactory = new GBeanInfoFactory(J2EEAppClientModuleImpl.class); + infoFactory.addReference("J2EEServer", J2EEServer.class); + infoFactory.addReference("J2EEApplication", J2EEApplication.class); + + infoFactory.addAttribute("deploymentDescriptor", String.class, true); + + infoFactory.addAttribute("objectName", String.class, false); + infoFactory.addAttribute("server", String.class, false); + infoFactory.addAttribute("application", String.class, false); + infoFactory.addAttribute("javaVMs", String[].class, false); + + infoFactory.setConstructor(new String[]{ + "objectName", + "J2EEServer", + "J2EEApplication", + "deploymentDescriptor"}); + + GBEAN_INFO = infoFactory.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +}