This document is basically a brain dump of how V3 is organized today with some insights on how it could be re-architected along the V3 engineering effort.
Change History
| Version | Comments | Owner | Wiki Revisions |
|---|---|---|---|
| 0.1 | Initial version | Jerome Dochez | 1 |
| 0.2 | Additional sections added | Jerome Dochez | 1 |
| 0.3 | Included feedback from community. Minor formatting changes. Additional hyperlinks. | Paul Sterk | 2-11 |
| 0.35 | Included new subversion repository information | Jerome Dochez | 6-11 |
GlassFish v3 is built around a Module subsystem specified by the Hundred Kilobyte Kernel (HK2)
project. Subsystem functionalities are declared through a Contract
/Service
implementation paradigm. HK2 Contracts identify and describe the building blocks or the extension points of an application. HK2 Services implement the Contracts. See HK2 Components
for more details.
A Module
is an encapsulated definition of reusable code. It offers Services
, declares a Modules's dependencies on other Services, has public APIs, and a private set of classes implementing these APIs. To summarize, a Module :
Defining a Module
is not always easy and will in most cases be an iterative process. Answering the following questions help to define a Module:
If you answer 'yes' to any of the above questions, the code should be encapsulated in a Module.
The easiest starting point is to check if your code offers more than one service. For instance, the current connector container offers 2 services to GlassFish v2: the JDBC driver container and the Java EE resource adapter container. These services could be defined as two Modules so they can be used independently.
From there, you also need to look into other services that your "code" offers to GlassFish. Don't create a Module just for the fun of it. One should create a Module only if it contains reusable code that can be used independently by other components (or just like above to make things more encapsulated/efficient).
Once you have determined a set of classes that you want to offer as a Module
, you need to start thinking about its definition. The definition is a name and a version that will be used by other modules to identify their dependency on your module.
The next aspect of modularization is to figure out the exact dependencies that your modules have. For instance, you may depend on the com.sun.enterprise:config-api. Note: the name of the module is constructed from a maven pom.xml using a group id and artifact id
). What else ?
It is quite important to understand those dependencies, not only to successfully compile your Module(s), but also to understand what runtime Services are necessary for your module to function properly.
So, here are suggested steps on how to define code into a Module:
Once you have that information, even in an initial raw format, you can start thinking about refactoring the code or reduce the dependency trail and so on.
GlassFish V3 is built as a distribution artifact. A distribution (distro) is a collection of Modules, and an artifact is the file that contains the distro. There will be various distributions of GlassFish V3 each providing a unique set of features. For example, there will be a distro of just the core Modules, currently called Nucleus, that will be targeted at OEMs. Also planned are Web, J2EE and other distros.
Elements of a distribution are integrated using maven2 repositories
. So, adding a Module
to a GlassFish v3 distribution requires three steps:
and create the jar file with the necessary hk2 manifest entries
to a maven repository.
Distributions are constructed from binary files procured from a maven repository. There is a complete separation between how to produce a particular Module versus how this Module is integrated into a distribution.
Each Module
can be integrated in various distributions. Hence, there cannot be any distribution specific knowledge introduced during the Module's build.
Although a Module could be potentially built with other tools, it is highly recommended that a Module be built with maven2. The Maven2 build environment
gives us the ability to run a number of maven plugins that can do some of the boiler plate activities such as HK2 manifest entries, components definition and so on.
A Module's source is usually comprised of the following artifacts (note: the directories shown below conform to the Maven Standard Directory Layout
:
defining the Module's compilation process and the dependencies.
Although it is helpful to know more about the Maven2 pom.xml file
, in most cases, it is not necessary to understand all the features of Maven to build a Module.
The basic structure of a pom.xml
is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<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>
<artifactId>bootstrap</artifactId>
<groupId>com.sun.enterprise.glassfish</groupId>
<version>10.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jvnet.glassfish</groupId>
<artifactId>glassfish-api</artifactId>
<packaging>hk2-jar</packaging>
<version>${project.parent.version}</version>
<name>Public APIs of Glassfish V3</name>
<developers>
<!-- information on the module's developers -->
</developers>
<dependencies>
<!-- Dependencies on other modules/jars -->
</dependencies>
<!-- Note: glassfish/bootstrap has java sources
at src/java. Include these elements to
comform to the Maven Standard Directory Layout -->
<build>
<sourceDirectory>src/main/java</sourceDirectory>
</build>
</project>
The parent definition is important as it includes all the system wide properties like version identification, compilation and packaging rules for your Module.
Other important information :
Adding a developer to the module is defined at pom.xml:developers
, but here is an example of adding myself as the Module owner (lead) and developer.
<developers>
<developer>
<id>dochez</id>
<name>Jerome Dochez</name>
<url>http://blogs.sun.com/dochez</url>
<organization>Sun Microsystems, Inc.</organization>
<roles>
<role>lead</role>
<role>developer</role>
</roles>
</developer>
</developers>
Once your Module uses other Modules to compile properly, you need to add a dependency declaration to the pom.xml
<dependencies>
<dependency>
<groupId>com.sun.enterprise</groupId>
<artifactId>hk2</artifactId>
<version>${hk2.version}</version>
</dependency>
</dependencies>
In the example above you can see that the module is using some HK2
core APIs. Whether you depend on a Module (hk2-jar) or a normal jar file does not change how you declare a dependency. The system will figure out the complete lists of dependencies.
Modules inherit the parent Module's licenses information, but if your Module is not part of GlassFish's source license agreements, you should add the following declaration to your pom.xml
<licenses>
<license>
<name>Apache 2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
Each Module has a high degree of freedom on where to host its source code. The only condition for a Module to be included in a GlassFish distribution is to publish the Module binaries to a maven repository. If a Module is hosted by a different java.net project than glassfish.dev.java.net, its pom.xml should include a source code management entry and a issue tracker management entry like this:
<scm>
<connection>scm:hg:http://mercurial.sfbay.sun.com/glassfish_v3</connection>
</scm>
<issueManagement>
<system>IssueTracker</system>
<url>https://glassfish.dev.java.net/servlets/ProjectIssues</url>
</issueManagement>
A number of maven plugins
have been developed to help the task of building Modules. These plugins will use the pom.xml
or the annotated classes to generate the metadata associated with a module like its HK2 manifest entries as well as its components definition. These plugins are declared in the GlassFish bootstrap pom.xml (used as a parent for each module pom.xml) therefore relieving the module owner from having to call the plugins themselves or create the metadata by hand.
It is still sometimes useful to call ant tasks
while building your Module, here is an example on how to do that :
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-sources</phase>
<configuration>
<tasks>
<copy file="jsp-api.mf"
toFile="${project.build.directory}/manifest.mf">
<filterset>
<filter token="VERSION" value="${jsp.spec.version}"/>
</filterset>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Javadocs can be automatically created by calling mvn javadoc:javadoc. You can also influence how the javadoc will be created by customizing the plugin that calls the javadoc tool.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<phase>javadoc</phase>
<goals>
<goal>javadoc</goal>
</goals>
<configuration>
<groups>
<group>
<title>JavaServer Pages API Documentation</title>
<packages>javax.servlet.jsp</packages>
</group>
</groups>
<bottom>Portions Copyright &copy; 1999-2002 The Apache Software Foundation.
All Rights Reserved. Portions Copyright &copy; 2005-2006 Sun Microsystems Inc.
All Rights Reserve
</bottom>
</configuration>
</execution>
</executions>
</plugin>
Each distribution will have a dashboard wiki page (see pe-10.0-SNAPSHOT
for instance) which will extract information from all the Modules of the distribution. The information in the pom.xml of each module is used to create the dashboard hence it is important to keep the information as up to date and complete as possible.
Each distribution will have a contributors dashboard where all contributors per module will be present. The information will be extracted from the pom.xml information as specified in 2.3.1.
GlassFish is now an HK2
executable. This means:
The bootstrap module (not an HK2 Module
since it is loaded by the application class loader) has the following responsibilities :
interface implementation. This module is identified as the unique import of the bootstrap module, therefore the bootstrap module cannot have more than one dependency declared in its manifest.
Once the bootstrap jar has identified, the first Glassfish V3 module called com.sun.enterprise:v3-core, the Module will be loaded and the ModuleStartup contract implementation will be instantiated and constructed according to HK2 component model
.
When embedded, GlassFish V3 startup sequence is essentially unchanged. The outer Java environment decides with which classloader the V3 bootstrap module should be loaded, essentially defining the parent classloader for V3.
At the end of this startup sequence, this is how the classloader hierarchy is established in V3 :
| Classloader | Classes Loaded |
|---|---|
| System Class Loader | JDK classes |
| Application Class Loader | all jar files present in the -cp parameter during the jvm invocation, or, in the embedded case, the classloader used to load the glassfish-{version}.jar file. |
| MaskingClassLoader | Parent classloader for all V3 modules, initialized by the glassfish-{version}.jar, its main responsibility is to mask the jdk classes. This means newer implementations of JDK bundled versions can be used without mechanisms such as the endorsed directories. |
| com.sun.enterprise:v3-core class loader |
Although programming with Modules
can be challenging, GlassFish cannot run efficiently based on user's actions alone. For example, if all the Modules forming a GlassFish distribution referenced each other, the entire set of Modules would be loaded at startup. This erases all the potential advantages of modularization.
To isolate the engineers from programming with Modules directly, there is a concept of Services
in glassfish. These services are usually Plain Old Java Objects (POJOs) implementing an interface. At runtime, glassfish relies on a Services implementation lookup to find the Services for a particular interface (called a Contract
).
Let's take an example. The com.sun.enterprise:appserv-api Module contains all GlassFish V3 public APIs. It contains an interface called Startup
. That interface defines code that must be run when GlassFish is started (somewhat equivalent to the Lifecycle implementations in V2). Any Modules in the GlassFish distribution can have one-to-many implementations of the Startup interfaces called startup services.
When glassfish is started, the Startup implementation code from the com.sun.enterprise:v3-core Module described earlier will do the following HK2 lookup :
Collection<Startup> startups = habitat.getAllByContract(Startup.class);
Even if v3-core Module does not directly import the Modules implementing the startup Services, the collection returned by the above code will contain those implementations. This is an implicit import of instances from one Module to another while the classloaders are not directly referencing each other.
Each Module containing one-to-many Startup implementations can also bring up other Modules through the dependency mechanisms. For instance the HttpService module which contains a Startup service can declare its dependency on the Grizzly Module. Once the Startup services have run successfully, this is how the classloader hierarchy will look like.
![]() |
In the example above, please note the following :
implementations. HttpService and DeploymentServices both offers Startup services implementation which are looked up by HK2 component manager, instantiated, injected and returned to the v3-core.
A new type of Service
or Contract
is just a plain java interface annotated with the @Contract
interface.
@Contract
public interface Startup {
}
Remember that @Contract annotated classes must be accessible from the Modules implementing the Contract (Service providers) as well as the Modules looking up such implementations. In the example above, the Startup
interface is defined in the appserv-api module and is imported by both the v3-core module which requests all Startup implementations and by the modules defining the implementations (HttpService module)
Adding a new Service
is as easy as defining a new POJO that implements a Contract and is annotated with the @Service
interface.
@Service
public class RandomService implements Startup, PostConstruct {
public void postConstruct() {
logger.info(“I am not that useful yet”);
}
}
The above example shows how to implement a Service by implementing the PostConstruct
ejb interface. Service implementations can be located in any module packaged in the distribution.
Configuration of a Service
can come from either the configuration file (domain.xml) or other component implementations. When a Service needs to be configured from the domain.xml, it should declare itself with the @Configured
interface.
The combination of @Attribute
and @Element
to bind to xml attributes and elements can be used to denote which information should be fetched from the configuration file.
@Configured
public class HttpService
implements Serializable {
@Element
protected AccessLog accessLog;
@Element(required=true)
protected List<HttpListener> httpListener = new ArrayList();
...
}
Although it could be conceivable that an annotated @Configured class is also a Service implementation, this sort of converged @Configured plus @Service component is discouraged. Most @Configured objects need to be available and be configured without an associated runtime (so the admin-gui can configure the http-service in the example used above without necessarily starting the http service). It is therefore recommended to split the configuration from the behavior into two POJOs and implement the following pattern using @ConfiguredBy
:
@Service
@ConfiguredBy(HttpService.class)
public void GrizzlyService implements Startup {
@Inject
private HttpService config;
...
}
A subset of services have already been identified and added to the org.jvnet.glassfish:appserv-api Module which represents the public APIs of the GlassFish implementation. Below is a brief introduction of these services. See later sections for more details:
| Service | Description |
|---|---|
| Startup | services which are run upon GlassFish startup. |
| Sniffer | services responsible for identifying deployment artifacts and setting up associated containers. |
| ArchiveHandler | services that recognize application bundle types (WAR, EAR...) |
| Deployer | services responsible for deploying artifacts to a particular container |
| AdminCommand | services which represent a CLI administrative command |
GlassFish v3 needs to support the convergence model for applications where users can ship application bits targeted to different containers all in the same package. This is a break from how we have traditionally considered application delivery in the Java EE world where each container had a dedicated bundle format. For instance, web containers expect war files, ejb containers expect jar files.
In v3, several types of applications can be co-packaged in the same bundle while still requiring some form of cooperation among the application parts (requiring a single class loader to load the application bits to be shared by all containers). There cannot be an assumption on the format of the bundle where a container can load the application bits from, therefore the containers do not control how the class loader for the applications bits are created, this is handled through another type of deployment service called ArchiveHandler.
There can be only one ArchiveHandler for a particular bundle type. The archive handler implementation will be responsible for creating an appropriate application class loader that can successfully load classes and resources from that bundle type. GlassFish V3 will create a parent classloader to be used by the ArchiveHandler when creating the application class loader. This parent class loader will allow the Glassfish runtime to dynamically add imports to the application (see below). Each Sniffer implementation has the ability to setup their associated containers, if the bundle appears to contain components they support. Once the sniffers have run successfully, all Deployer services currently found by HK2 will have a chance to deploy bits of the bundle to their associated containers.
Deployers will either claim part of the application bits or not. If a particular deployer instance successfully process a deployment request using the class loader created by the ArchiveHandler. the public APIs associated with that container (eg the Java EE APIs) will be added to the parent class loader (create above for that purpose).
Remember that supporting different bundle types is a desired feature. Therefore, power users can have the ability to create/register new ArchiveHandlers. Since ArchiveHandlers are responsible for creating the classloaders, there is no possibility to directly add the container's public API to these classloaders. This is because the ArchiveHandlers are simple java.lang.ClassLoader implementations. This is the reason behind the creation of this dynamic parent class loader.
However, there is a slight limitation to this scheme: the ClassLoader implementation returned by the ArchiveHandler should support the registration of java.lang.instrument.ClassFileTransformer instances. This supports bytecode enhancement dependent technologies like JPA. The EjbClassLoader and WebClassLoader that we ship with V3 both support such a registration.
In the diagram below, we have two containers: one application being deployed to both containers and one random library module used by one of the container. Note the following :
In the second diagram, you will see a simplified version of the first diagram showing the relationships between two applications and the containers into which they are successfully deployed. Note the following :
![]() |
![]() |
Implementing persistence in V3 involves several challenges due to the following:
The following patterns have been identified :
To resolve the above problems, a shared library Module will be introduced. This Module will load all jar files located in the glassfish/lib and glassfish/javadb/lib directories (remember that v3 modules and jars will be relocated somewhere else). This shared library will have access to the JDBC drivers as well as javadb runtime.
The solution described above is illustrated by Figure 4 below. The number in parentheses indicates which class loader relationship that will satisfy the requirement.
Applications can load JDBC drivers using the Class.forName() API. The parent class loader of the application class loader (named the application container class loader) will include the shared library class loader. It also will give access to the public APIs of an application (1)
In Java SE mode, applications use javax.persistence.PersistenceProvider.createEntityManagerFactory() API to create an entity manager. Applications use a persistenceUnitName parameter to identify the provider in the persistence.xml file. HK2 will make the META-INF/services resolution for the PersistenceProvider.java implementation and JPA will be loaded like any other HK2 service.
The JDBC driver is provided by some non-portable persistence.xml properties and is loaded directly by the persistence provider (2)
In Java EE, there is a need to add ClassFileTransformers to the application class loader. This is a bit tricky as we don't necessarily provide the class loader for the application bits (see Deployment above). JPA infrastructure will have a Deployer implementation, therefore the prepare phase should be used by the JPADeployer to pre-load classes that may require bytecode enhancements. During the prepare phase, the JPADeployer should also add some java.lang.intrument.ClassFileTransformers) instances to the DeploymentContext. The Deployment backend will then recreate a new class loader, register all installed ClassFileTransformers in this new class loader instances and will invoke the load phase with the new classloader.
Normal HK2 Service resolution should suffice to resolve the JPA provider based on the META-INF/services entries.
Naming Service will be available though the HK2 Service Resolution Mechanism, from which the connection pool can be looked up. After wiring up the connection pool with the JPA provider, the entity manager can be created by the deployment code and injected in the application code.
Normal class loading delegation should be enough to support such use cases.
![]() |
Containers are entities that can run applications (e.e., web container, ejb, etc.). Since such containers can be installed or removed from a GlassFish V3 installation, there is no special code referencing different application containers like Switch.java in V2.
Containers have the ability to install themselves in an existing GlassFish installation with the following Services implementations :
Like everything in V3, we rely on HK2
components to identify administrative commands. So, in this case, the AdminCommand interface is annotated with @Contract. As a result, to add a new command to GlassFish V3 is to create a Service implementing the AdminCommand interface and the runtime will find it :
package com.foo.bar;
@Service(name="super")
public class MySuperCommand implements AdminCommand {
...
}
Now this is nice but we can do better. Since admin commands are Services, we can use injection. So, if you want to have access to the domain configuration, you do the following:
@Inject Domain domain;
and the domain information will be injected in the instance field before the command execute() is invoked. That's nice, but why not extend this to the command parameters. Too many times, I have seen command implementation code just ensure that all mandatory parameters to the command are present, values are correct, and extraction from the String representation.
This is where the new annotation @Param becomes useful. It can annotate any instance field of the command implementation with the @Param annotation to make it a command parameter. So for instance adding the following:
@Param String name
adds a name parameter to the command. Of course, parameters can be optional
@Param(optional=true) String myoptionalparam
or the default parameter (but there can only be one of course)
@Param(default=true) String path
so you can now do :
asadmin deploy --path foo.waror
asadmin deploy foo.war
Also, the @Param tag is automatically linked to the required LocalStrings.properties resource file of your classloader. So, when you add the
com.sun.foo.bar.mysupercommand=Some random super command com.sun.foo.bar.mysupercommand.path=path to the file the command applies to.
strings to your LocalStrings.properties, the system will find them and use it for any type of error checking or help :
$prompt>asadmin super FAILURE : super command requires the path parameter : path to the file the command applies to. $prompt>asadmin super --help Some random super command Parameters : path : path to the file the command applies to.
The above behaviours are completely handled by the system. The command will not be executed as long as all mandatory parameters are provided by the users. There is more to do, of course, like automatic help page and localized page creation. Also, there should be some maven 2 plugins developed to automate page creation and ensure that all strings are properly localized.
Although this information will most likely change and is not entirely implemented, this is an introduction to how we will organize the source code in V3.
The bootstrap directory is not going to be moved forward, but we will use a directory layout to separate and represent modules segments. Functionalities linked to packaging are moved to the distribution modules.
Source code is managed using Subversion
for now. However, we plan to move to mercurial at some point. The Subversion workspace is organized to follow the module infrastructure that we will be using in V3.
To checkout the entire glassfish workspace that are not yet used by the V3 runtime (and therefore were not moved to a corresponding module directory), you can do the following :
svn checkout https://svn.dev.java.net/svn/glassfish-svn/trunk/v2
However, unless you plan to move code from the old modules to the new structure, you do not need to checkout the entire workspace, in general, you can just check out the code currently used in V3 by doing :
svn checkout https://svn.dev.java.net/svn/glassfish-svn/trunk/v3
To subscribe to the svn notifications for the changes, send an e-mail to commits-subscribe@glassfish-svn.dev.java.net
Modules are organized following the maven best practice pattern
.
Although each module can use a dedicated scm repository, it is important to follow that structure for consistency and tool support.
See V3 module structure for a complete description. However, for the most simple cases, it should be the following files/directories:
| File | Description |
|---|---|
| pom.xml | maven build file |
| src/main/java | module's sources |
| src/main/resources | module's resources like localized strings, xml... |
| src/tests/... | module's unit tests |
In V2, the workspace was organized with sub-modules, each sub-module could be independently checked out or if you wanted to checkout the entire workspace, you would do so from the bootstrap module. For instance this is a simplified view of the V2 CVS workspace
| Module | Description |
|---|---|
| bootstrap | contains all project wide settings, main build scripts etc. |
| appserv-commons | contains code shared by the different GlassFish sub components (Web Container, Deployment, EJB container...) |
| admin-core/config-api | contains the domain.xml binding classes generated from schema2beans |
| ejb-api | EJB 3.0 javax.ejb API sources |
In the current V3 workspace, the sources which are currently used by the V3 runtime have been moved to a new location that reflect the module in which the .class files are packaged. The workspace is also organized in a tree like structure (as opposed to mainly flat like in V2 with all modules at the top-level).
Modules will be grouped into functional areas and moved under specific directories. A user that wishes to checkout the entire V3 workspace should do so by issuing the command described in IV.1. However, developers that wish to only work in a specific area should checkout the set of Modules that are identified in that area.
The following areas have been already identified. This will evolve over time:
| Directory | Description |
|---|---|
| v3/web | web related technologies (jsp, jsf...) |
| v3/ejb | ejb related technologies |
| v3/core | v3 core infrastructures |
| v3/admin | administration related modules |
| v3/extras | adminGUI and other tools |
| v3/api | Java EE APIS |
| v3/build | Build related tools like maven plugins |
For instance, under glassfish_v3/web, you will find subdirectories for each module that are part of our web profile. Now, let's say you need to move some code from appserv-core to the new V3 module structure (in say web/appserv-webtier module), you could only checkout the appropriate modules :
svn checkout https://svn.dev.java.net/svn/glassfish-svn/trunk/v3/appserv-core svn checkout https://svn.dev.java.net/svn/glassfish-svn/trunk/v3/web/appserv-webtier
Once we will complete the switch to Mercurial, such tree based organization does not support checking out part of the tree. So, we will most likely move each sub-directory under glassfish_v3 to a new Hg repository.
Modules are grouped using a groupId as defined in the module's pom.xml. All GlassFish module should follow this consistent naming and directory structure
| Main groupId | Function Area | Module name | Resulting maven Id | source location |
|---|---|---|---|---|
| org.glassfish | web | appserv-webtier | org.glassfish.web:appserv-webtier | v3/web/appserv-webtier |
| org.glassfish | admin | config-api | org.glassfish.admin:config-api | v3/admin/config-api |
| org.glassfish | core | kernel | org.glassfish.core:kernel | v3/core/kernel |
Basic understanding of maven and maven repositories is necessary to build V3. Also, at each level, users are able to do a mvn command to build a Module, create a functional set of Modules, or the entire V3 workspace.
| Command | Description |
|---|---|
| mvn clean | cleans the binary outputs (.class, and .jar files) from the module target directory. Does not remove the Module artifact from the local maven repository. |
| mvn install | builds and install the binary artifact in the local maven repository. |
| mvn javadoc:javadoc | creates javadoc |
So for instance if I run mvn install from the v3 directory, I will build the entire GlassFish V3, if I build under v3/web I will build all the web related modules, if I build v3/web/appserv-webtier, I only build the appserv-webtier module.
Artifacts cannot be published directly to the global HTTP maven repositories because a certain number of integration tests need to happen. When a developer feels confident that his code is robust and has made enough integration tests on his local machine (by building a distribution and running tests), he will check in the sources. Hudson, the continuous building system, will monitor checkins and will trigger a build/test/publish cycle each time a developer checks in a change set.
One of the big activity of V3 will be to move code from their current module to a new directory that reflect the runtime module in which the .class will be packaged. How can you move files without loosing history :
svn checkout https://svn.dev.java.net/svn/glassfish-svn/trunk/v2/appserv-core svn checkout https://svn.dev.java.net/svn/glassfish-svn/trunk/v3/web/appserv-webtier
assuming you are located in your home directory, you now have 2 subdirectories, appserv-core and v3
cd ~/v3/web/appserv-webtier/src/main/java/com/sun/entreprise svn mv ~/v2/appserv-core/src/java/com/sun/enterprise/FooBar.java .
and commit to have the old file deleted from appserv-core and the new addition to v3/web/appserv-webtier without loosing the commit history. You can also move entire directories following the same pattern as above. Do not do svn rm and svn add as you would loose the SCM history associated with the file you are trying to move.
Distributions are created by assembling jars and other artifacts. There is a flexible distribution description mechanism based on maven pom file for binary dependencies and ant scripts for the other types of artifacts. For more details about this process, refer to V3DistributionAssembly
HK2, the java.net project for our module subsystem and lightweight component model, has a separate java.net project located at hk2.dev.java.net
.
HK2 sources are stored in a Subversion repository, so checking out sources is usually done with
svn checkout https://hk2.dev.java.net/svn/hk2/trunk