GlassFish V3 Embedded: Requirements

GlassFish V3 will be the next major release of the GlassFish application server. The focus of the release is modularization, enablement of non Java EE containers, and embed-ability. This page is exploring the embedded requirements for V3, that will make applications more easily testable, and enable as a component in the grid infrastructure (like Caroline).

Problem statement

GlassFish V3 is a pure Java application, written in a modular and extensible way (HK2 and OSGI). It will become important to make it embeddable in a bigger Java Application, like an IDE (NetBeans or Eclipse), or like a software appliance. This will impose some requirements on how V3 is written so that it can run as a standalone Java Application, or within the context of another application.

General requirements

  • A user-written Java program needs to be be able to start GFv3 in the same JVM.
  • Multiple GFv3 must be able to co-exist in the same JVM.
  • V3 needs to be able to run without requiring certain VM launch options. If this forces GFv3 to disable some features, that is OK.
  • Need Java APIs to start/stop the V3 runtime from within a Java Application
  • Need Java APIs to change critical params from existing config domain.xml like: portNumber.
  • A V3 embedded system should rely on the minimum set of system properties (ideally 0), since system properties are like global variables.
  • Need well defined set of system properties needed (if the target of 0 cannot be achieve) by a V3 runtime
  • Need a way to define a V3 specific logger so that the V3 runtime log messages can be separated from the embedding application
  • The Start/Run/Stop cycles of a V3 runtimes should be able to be performed multiple times without side effects (memory leaks, resource/jar locking,...)
  • The V3 runtime Security Manager should be aware of possible other security manager from the embedding application, and adapt itself to either reuse a security manager, modify it.
  • The V3 runtime should list/know all the JVM global resources it needs (security manager, xml parsing service, logging service, etc:
    • java.util.logging.config.file
    • security manager
    • ...
  • Need for a GlassFish V3 distro constructor that would create the minimal set of GF V3 modules for running a specific web application. For example, if the Hudson web application needs to bundles a minimal runtime as an execution environment, the distro constructor should allows to pick and choose what is needed (hk2 core, servlet container, no JSP, no JSF, no AMX, etc).
  • Need for an execution environment that does not requires the 'domain' concept on disk. It should be possible to create a domain only in memory (based on a template) that can be used as an execution environment of a single web application.

NetBeans:

Some initial testing has been done with running a V3 runtime inside the NetBeans 6.1 beta IDE.

Here is the snippet of code:

public void run() {
        ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader();
        ExtendedClassLoader loader = null;
        //    origClassLoader = (ClassLoader) Lookup.getDefault().lookup (ClassLoader.class);
        fireStartProgressEvent(StateType.RUNNING, createProgressMessage("MSG_START_SERVER_IN_PROGRESS"));
            String hk2Home = ip.getProperty(Hk2PluginProperties.PROPERTY_HK2_HOME);
       try {
         File logging = new File(hk2Home + "/domains/domain1/config/logging.properties");
        System.setProperty("java.util.logging.config.file", logging.getAbsolutePath());

            loader = new ExtendedClassLoader(Hk2Embedded.class.getClassLoader());
 
            String jarLocation = hk2Home + "/" + GFV3_MODULES_DIR_NAME + "/" + GFV3_SNAPSHOT_JAR_NAME;
            File fi = new File(jarLocation);
            System.out.println("fi="+fi+fi.exists());
            loader.addURL(fi);
            //    System.setProperty("hk2.port", "8888");
            if (loader != null) {

                Thread.currentThread().setContextClassLoader(loader);
                try {

                    Class realhk2MainClass = loader.loadClass("com.sun.enterprise.glassfish.bootstrap.ASMain");
                    String arg[]={};
                    Method startMethod = realhk2MainClass.getMethod("main", new Class[]{arg.getClass()});//NOI18N
                    startMethod.invoke(realhk2MainClass, new Object[]{arg});

                    fireStartProgressEvent(StateType.COMPLETED, createProgressMessage("MSG_SERVER_STARTED")); // NOI18N

                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException ex) {
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    fireStartProgressEvent(StateType.FAILED, createProgressMessage("MSG_START_SERVER_FAILED"));

                }


            }
        } catch (Throwable ex) {
            //Suppressing exception while trying to obtain admin host port value
            fireStartProgressEvent(StateType.FAILED, createProgressMessage("MSG_START_SERVER_FAILED"));
            ex.printStackTrace();
        } finally {
            Thread.currentThread().setContextClassLoader(origClassLoader);

        }
    }

Currently, the latest GF V3 securityManager managenment handles correctly the existence of the Nb security Manager. Still some samll issues regarding some policies enforced by NetBeans as warning regarding loading resources from a root dir in an archive:

INFO [org.netbeans.ProxyClassLoader]
java.lang.IllegalStateException: You are trying to access file: skip-annotation-class-list from the default package. Please see http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/classpath.html#default_package
	at org.netbeans.ProxyClassLoader.printDefaultPackageWarning(ProxyClassLoader.java:524)
	at org.netbeans.ProxyClassLoader.getResource(ProxyClassLoader.java:297)
	at java.lang.ClassLoader.getResource(ClassLoader.java:1027)
	at java.lang.ClassLoader.getResource(ClassLoader.java:1027)
	at java.lang.ClassLoader.getResource(ClassLoader.java:1027)
	at java.lang.ClassLoader.getResource(ClassLoader.java:1027)
	at com.sun.enterprise.module.impl.ModuleClassLoader.getResource(ModuleClassLoader.java:98)

Eclipse OSGI

The lastest current GlassFish V3 code supports both HK2 mode and OSGI mode. The officially supported OSGI runtime is Felix, but it is not possible to run the entire GlassFish V3 embedded in an Eclipse 3.3 and 3.4 IDE, using a bundle wrapper that loads the critical GlassFish bundles dynamically.
More work needs to happen on the V3 side regarding JARs not available as OSGI modules (jmx-remote, tiger-types, and xml support jar (available in JDK 1.6 only and not 1.5).