blob: 6c26f88d91f0fc91f57e420a8950f4a7d91d7c81 [file] [log] [blame]
/*
* Copyright (c) 2008, 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 com.sun.enterprise.glassfish.bootstrap;
import com.sun.enterprise.module.bootstrap.ArgumentManager;
import static com.sun.enterprise.module.bootstrap.ArgumentManager.argsToMap;
import com.sun.enterprise.module.bootstrap.StartupContext;
import com.sun.enterprise.module.bootstrap.Which;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Utility class used by bootstrap module.
* Most of the code is moved from {@link ASMain} or {@link GlassFishMain}to this class to keep them
* as small as possible and to improve reusability when GlassFish is launched in other modes (e.g., karaf).
*
* @author Sanjeeb.Sahoo@Sun.COM
*/
public class MainHelper {
private static Logger logger = LogFacade.BOOTSTRAP_LOGGER;
/*protected*/
static void checkJdkVersion() {
int major = getMajorJdkVersion();
int minor = getMinorJdkVersion();
//In case of JDK1 to JDK8 the major version would be 1 always.Starting from
//JDK9 the major verion would be the real major version e.g in case
// of JDK9 major version is 9.So in that case checking the major version only
if (major < 9) {
if (minor < 8) {
logger.log(Level.SEVERE, LogFacade.BOOTSTRAP_INCORRECT_JDKVERSION, new Object[]{8, minor});
System.exit(1);
}
}
}
private static int getMajorJdkVersion() {
String jv = System.getProperty("java.version");
String[] split = jv.split("[\\._\\-]+");
if (split.length > 0) {
return Integer.parseInt(split[0]);
}
return -1;
}
private static int getMinorJdkVersion() {
// this is a subset of the code in com.sun.enterprise.util.JDK
// this module has no dependencies on util code so it was dragged in here.
try {
String jv = System.getProperty("java.version");
String[] ss = jv.split("\\.");
if (ss == null || ss.length < 3 || !ss[0].equals("1"))
return 1;
return Integer.parseInt(ss[1]);
}
catch (Exception e) {
return 1;
}
}
static String whichPlatform() {
String platform = Constants.Platform.Felix.toString(); // default is Felix
// first check the system props
String temp = System.getProperty(Constants.PLATFORM_PROPERTY_KEY);
if (temp == null || temp.trim().length() <= 0) {
// not in sys props -- check environment
temp = System.getenv(Constants.PLATFORM_PROPERTY_KEY);
}
String trimtemp;
if (temp != null && (trimtemp = temp.trim()).length() != 0) {
platform = trimtemp;
}
return platform;
}
public static Properties parseAsEnv(File installRoot) {
Properties asenvProps = new Properties();
// let's read the asenv.conf
File configDir = new File(installRoot, "config");
File asenv = getAsEnvConf(configDir);
if (!asenv.exists()) {
if (logger.isLoggable(Level.FINE)) {
logger.fine(asenv.getAbsolutePath() + " not found, ignoring");
}
return asenvProps;
}
LineNumberReader lnReader = null;
try {
lnReader = new LineNumberReader(new FileReader(asenv));
String line = lnReader.readLine();
// most of the asenv.conf values have surrounding "", remove them
// and on Windows, they start with SET XXX=YYY
Pattern p = Pattern.compile("(?i)(set +)?([^=]*)=\"?([^\"]*)\"?");
while (line != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
File f = new File(m.group(3));
if (!f.isAbsolute()) {
f = new File(configDir, m.group(3));
if (f.exists()) {
asenvProps.put(m.group(2), f.getAbsolutePath());
} else {
asenvProps.put(m.group(2), m.group(3));
}
} else {
asenvProps.put(m.group(2), m.group(3));
}
}
line = lnReader.readLine();
}
} catch (IOException ioe) {
throw new RuntimeException("Error opening asenv.conf : ", ioe);
} finally {
try {
if (lnReader != null)
lnReader.close();
} catch (IOException ioe) {
// ignore
}
}
return asenvProps;
}
void addPaths(File dir, String[] jarPrefixes, List<URL> urls) throws MalformedURLException {
File[] jars = dir.listFiles();
if (jars != null) {
for (File f : jars) {
for (String prefix : jarPrefixes) {
String name = f.getName();
if (name.startsWith(prefix) && name.endsWith(".jar"))
urls.add(f.toURI().toURL());
}
}
}
}
/**
* Figures out the asenv.conf file to load.
*/
private static File getAsEnvConf(File configDir) {
String osName = System.getProperty("os.name");
if (osName.indexOf("Windows") == -1) {
return new File(configDir, "asenv.conf");
} else {
return new File(configDir, "asenv.bat");
}
}
/**
* Determines the root directory of the domain that we'll start.
*/
/*package*/ static File getDomainRoot(Properties args, Properties asEnv) {
// first see if it is specified directly
String domainDir = getParam(args, "domaindir");
if (ok(domainDir))
return new File(domainDir);
// now see if they specified the domain name -- we will look in the
// default domains-dir
File defDomainsRoot = getDefaultDomainsDir(asEnv);
String domainName = getParam(args, "domain");
if (ok(domainName))
return new File(defDomainsRoot, domainName);
// OK -- they specified nothing. Get the one-and-only domain in the
// domains-dir
return getDefaultDomain(defDomainsRoot);
}
/**
* Verifies correctness of the root directory of the domain that we'll start and
* sets the system property called {@link com.sun.enterprise.glassfish.bootstrap.Constants#INSTANCE_ROOT_PROP_NAME}.
*/
/*package*/ void verifyAndSetDomainRoot(File domainRoot) {
verifyDomainRoot(domainRoot);
domainRoot = absolutize(domainRoot);
System.setProperty(Constants.INSTANCE_ROOT_PROP_NAME, domainRoot.getPath());
}
/**
* Verifies correctness of the root directory of the domain that we'll start.
*
* @param domainRoot
*/
/*package*/
static void verifyDomainRoot(File domainRoot) {
String msg = null;
if (domainRoot == null)
msg = "Internal Error: The domain dir is null.";
else if (!domainRoot.exists())
msg = "the domain directory does not exist";
else if (!domainRoot.isDirectory())
msg = "the domain directory is not a directory.";
else if (!domainRoot.canWrite())
msg = "the domain directory is not writable.";
else if (!new File(domainRoot, "config").isDirectory())
msg = "the domain directory is corrupt - there is no config subdirectory.";
if (msg != null)
throw new RuntimeException(msg);
}
private static File getDefaultDomainsDir(Properties asEnv) {
// note: 99% error detection!
String dirname = asEnv.getProperty(Constants.DEFAULT_DOMAINS_DIR_PROPNAME);
if (!ok(dirname))
throw new RuntimeException(Constants.DEFAULT_DOMAINS_DIR_PROPNAME + " is not set.");
File domainsDir = absolutize(new File(dirname));
if (!domainsDir.isDirectory())
throw new RuntimeException(Constants.DEFAULT_DOMAINS_DIR_PROPNAME +
"[" + dirname + "]" +
" is specifying a file that is NOT a directory.");
return domainsDir;
}
private static File getDefaultDomain(File domainsDir) {
File[] domains = domainsDir.listFiles(new FileFilter() {
public boolean accept(File f) { return f.isDirectory(); }
});
// By default we will start an unspecified domain iff it is the only
// domain in the default domains dir
if (domains == null || domains.length == 0)
throw new RuntimeException("no domain directories found under " + domainsDir);
if (domains.length > 1)
throw new RuntimeException("Multiple domains[" + domains.length + "] found under "
+ domainsDir + " -- you must specify a domain name as -domain <name>");
return domains[0];
}
private static boolean ok(String s) {
return s != null && s.length() > 0;
}
private static String getParam(Properties map, String name) {
// allow both "-" and "--"
String val = map.getProperty("-" + name);
if (val == null)
val = map.getProperty("--" + name);
return val;
}
private static File absolutize(File f) {
try {
return f.getCanonicalFile();
}
catch (Exception e) {
return f.getAbsoluteFile();
}
}
/**
* CLI or any other client needs to ALWAYS pass in the instanceDir for
* instances.
*
* @param args
* @param asEnv
* @return
*/
static File getInstanceRoot(Properties args, Properties asEnv) {
String instanceDir = getParam(args, "instancedir");
if (ok(instanceDir))
return new File(instanceDir);
return null;
}
/* package */
static File findInstallRoot() {
File bootstrapFile = findBootstrapFile(); // glassfish/modules/glassfish.jar
return bootstrapFile.getParentFile().getParentFile(); // glassfish/
}
/* package */
static File findInstanceRoot(File installRoot, Properties args) {
Properties asEnv = parseAsEnv(installRoot);
// IMPORTANT - check for instance BEFORE domain. We will always come up
// with a default domain but there is no such thing sa a default instance
File instanceDir = getInstanceRoot(args, asEnv);
if (instanceDir == null) {
// that means that this is a DAS.
instanceDir = getDomainRoot(args, asEnv);
}
verifyDomainRoot(instanceDir);
return instanceDir;
}
static File findInstanceRoot(File installRoot, String[] args) {
return findInstanceRoot(installRoot, ArgumentManager.argsToMap(args));
}
private static File findBootstrapFile() {
try {
return Which.jarFile(ASMain.class);
} catch (IOException e) {
throw new RuntimeException("Cannot get bootstrap path from "
+ ASMain.class + " class location, aborting");
}
}
static Properties buildStartupContext(String platform, File installRoot, File instanceRoot, String[] args) {
Properties ctx = com.sun.enterprise.module.bootstrap.ArgumentManager.argsToMap(args);
ctx.setProperty(StartupContext.TIME_ZERO_NAME, Long.toString(System.currentTimeMillis()));
ctx.setProperty(Constants.PLATFORM_PROPERTY_KEY, platform);
ctx.setProperty(Constants.INSTALL_ROOT_PROP_NAME, installRoot.getAbsolutePath());
ctx.setProperty(Constants.INSTALL_ROOT_URI_PROP_NAME, installRoot.toURI().toString());
ctx.setProperty(Constants.INSTANCE_ROOT_PROP_NAME, instanceRoot.getAbsolutePath());
ctx.setProperty(Constants.INSTANCE_ROOT_URI_PROP_NAME, instanceRoot.toURI().toString());
if (ctx.getProperty(StartupContext.STARTUP_MODULE_NAME) == null) {
ctx.setProperty(StartupContext.STARTUP_MODULE_NAME, Constants.GF_KERNEL);
}
// temporary hack until CLI does that for us.
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-upgrade")) {
if (i + 1 < args.length && !args[i + 1].equals("false")) {
ctx.setProperty(StartupContext.STARTUP_MODULESTARTUP_NAME, "upgrade");
}
}
}
addRawStartupInfo(args, ctx);
mergePlatformConfiguration(ctx);
return ctx;
}
public static Properties buildStaticStartupContext(long timeZero, String... args) {
checkJdkVersion();
Properties ctx = argsToMap(args);
ctx.setProperty(Constants.PLATFORM_PROPERTY_KEY, "Static");
buildStartupContext(ctx);
addRawStartupInfo(args, ctx);
// Reset time zero with the real value. We can't do this before buildStartupContext()
// because it has an optimization that is triggered by this key.
ctx.setProperty(StartupContext.TIME_ZERO_NAME, Long.toString(timeZero));
// Config variable substitution (and maybe other downstream code) relies on
// some values in System properties, so copy them in.
for (String key : new String[]{Constants.INSTALL_ROOT_PROP_NAME,
Constants.INSTANCE_ROOT_URI_PROP_NAME,
Constants.INSTALL_ROOT_PROP_NAME,
Constants.INSTALL_ROOT_URI_PROP_NAME}) {
System.setProperty(key, ctx.getProperty(key));
}
return ctx;
}
public static void buildStartupContext(Properties ctx) {
if (ctx.getProperty(StartupContext.TIME_ZERO_NAME) == null) {
ctx.setProperty(StartupContext.TIME_ZERO_NAME, Long.toString(System.currentTimeMillis()));
} else {
// Optimisation
// Skip the rest of the code. We assume that we are called from GlassFishMain
// which already passes a properly populated properties object.
return;
}
if (ctx.getProperty(Constants.PLATFORM_PROPERTY_KEY) == null) {
ctx.setProperty(Constants.PLATFORM_PROPERTY_KEY, Constants.Platform.Felix.name());
}
if (ctx.getProperty(Constants.INSTALL_ROOT_PROP_NAME) == null) {
File installRoot = findInstallRoot();
ctx.setProperty(Constants.INSTALL_ROOT_PROP_NAME, installRoot.getAbsolutePath());
ctx.setProperty(Constants.INSTALL_ROOT_URI_PROP_NAME, installRoot.toURI().toString());
}
if (ctx.getProperty(Constants.INSTANCE_ROOT_PROP_NAME) == null) {
File installRoot = new File(ctx.getProperty(Constants.INSTALL_ROOT_PROP_NAME));
File instanceRoot = findInstanceRoot(installRoot, ctx);
ctx.setProperty(Constants.INSTANCE_ROOT_PROP_NAME, instanceRoot.getAbsolutePath());
ctx.setProperty(Constants.INSTANCE_ROOT_URI_PROP_NAME, instanceRoot.toURI().toString());
}
if (ctx.getProperty(StartupContext.STARTUP_MODULE_NAME) == null) {
ctx.setProperty(StartupContext.STARTUP_MODULE_NAME, Constants.GF_KERNEL);
}
if (!ctx.contains(Constants.NO_FORCED_SHUTDOWN)) {
// Since we are in non-embedded mode, we set this property to false unless user has specified it
// When set to false, the VM will exit when server fails to startup for whatever reason.
// See AppServerStartup.java
ctx.setProperty(Constants.NO_FORCED_SHUTDOWN, Boolean.FALSE.toString());
}
mergePlatformConfiguration(ctx);
}
/**
* Need the raw unprocessed args for RestartDomainCommand in case we were NOT started
* by CLI
*
* @param args raw args to this main()
* @param p the properties to save as a system property
*/
private static void addRawStartupInfo(final String[] args, final Properties p) {
//package the args...
StringBuilder sb = new StringBuilder();
for (int i = 0; i < args.length; i++) {
if (i > 0)
sb.append(Constants.ARG_SEP);
sb.append(args[i]);
}
if (!wasStartedByCLI(p)) {
// no sense doing this if we were started by CLI...
p.put(Constants.ORIGINAL_CP, System.getProperty("java.class.path"));
p.put(Constants.ORIGINAL_CN, ASMain.class.getName());
p.put(Constants.ORIGINAL_ARGS, sb.toString());
}
}
private static boolean wasStartedByCLI(final Properties props) {
// if we were started by CLI there will be some special args set...
return
props.getProperty("-asadmin-classpath") != null &&
props.getProperty("-asadmin-classname") != null &&
props.getProperty("-asadmin-args") != null;
}
/**
* This method is responsible setting up launcher class loader which is then used while calling
* {@link org.glassfish.embeddable.GlassFishRuntime#bootstrap(org.glassfish.embeddable.BootstrapProperties, ClassLoader)}.
*
* This launcher class loader's delegation hierarchy looks like this:
* launcher class loader
* -> OSGi framework launcher class loader
* -> extension class loader
* -> null (bootstrap loader)
* We first create what we call "OSGi framework launcher class loader," that has
* classes that we want to be visible via system bundle.
* Then we create launcher class loader which has {@link OSGiGlassFishRuntimeBuilder} and its dependencies in
* its search path. We set the former one as the parent of this, there by sharing the same copy of
* GlassFish API classes and also making OSGi classes visible to OSGiGlassFishRuntimeBuilder.
*
* We could have merged all the jars into one class loader and called it the launcher class loader, but
* then such a loader, when set as the bundle parent loader for all OSGi classloading delegations, would make
* more things visible than desired. Please note, glassfish.jar has a very long dependency chain. See
* glassfish issue 13287 for the kinds of problems it can create.
*
* @see #createOSGiFrameworkLauncherCL(java.util.Properties, ClassLoader)
* @param delegate: Parent class loader for the launcher class loader.
*/
static ClassLoader createLauncherCL(Properties ctx, ClassLoader delegate) {
try {
ClassLoader osgiFWLauncherCL = createOSGiFrameworkLauncherCL(ctx, delegate);
ClassLoaderBuilder clb = new ClassLoaderBuilder(ctx, osgiFWLauncherCL);
clb.addLauncherJar(); // glassfish.jar
return clb.build();
} catch (IOException e) {
throw new Error(e);
}
}
/**
* This method is responsible for setting up the what we call "OSGi framework launcher class loader." It has
* the following classes/jars in its search path:
* - OSGi framework classes,
* - GlassFish bootstrap apis (simple-glassfish-api.jar)
* - jdk tools.jar classpath.
* OSGi framework classes are there because we want to launch the framework.
* simple-glassfish-api.jar is needed, because we need those classes higher up in the class loader chain otherwise
* {@link com.sun.enterprise.glassfish.bootstrap.GlassFishMain.Launcher} won't be able to see the same copy that's
* used by rest of the system.
* tools.jar is needed because its packages, which are exported via system bundle, are consumed by EJBC.
* This class loader is configured to be the delegate for all bundle class loaders by setting
* org.osgi.framework.bundle.parent=framework in OSGi configuration. Since this is the delegate for all bundle
* class loaders, one should be very careful about adding stuff here, as it not only affects performance, it also
* affects functionality as explained in GlassFish issue 13287.
*
* @param delegate: Parent class loader for this class loader.
*/
private static ClassLoader createOSGiFrameworkLauncherCL(Properties ctx, ClassLoader delegate) {
try {
ClassLoaderBuilder clb = new ClassLoaderBuilder(ctx, delegate);
clb.addFrameworkJars();
clb.addBootstrapApiJar(); // simple-glassfish-api.jar
if (getMajorJdkVersion() < 9) {
clb.addJDKToolsJar();
}
return clb.build();
} catch (IOException e) {
throw new Error(e);
}
}
/**
* Store relevant information in system properties.
*
* @param ctx
*/
static void setSystemProperties(Properties ctx) {
// Set the system property if downstream code wants to know about it
System.setProperty(Constants.PLATFORM_PROPERTY_KEY, ctx.getProperty(Constants.PLATFORM_PROPERTY_KEY));
}
static void mergePlatformConfiguration(Properties ctx) {
Properties platformConf = null;
try {
platformConf = PlatformHelper.getPlatformHelper(ctx).readPlatformConfiguration();
} catch (IOException e) {
throw new RuntimeException(e); // TODO(Sahoo): Proper Exception Handling
}
platformConf.putAll(ctx);
Util.substVars(platformConf);
// Starting with GlassFish 3.1.2, we allow user to overrride values specified in OSGi config file by
// corresponding values as set via System propereties. There are two properties that we must always read
// from OSGi config file. They are felix.fileinstall.dir and felix.fileinstall.log.level, as their values have
// changed incompatibly from 3.1 to 3.1.1, but we are not able to change domain.xml in 3.1.1 for
// compatibility reasons.
Util.overrideBySystemProps(platformConf, Arrays.asList("felix.fileinstall.dir", "felix.fileinstall.log.level"));
ctx.clear();
ctx.putAll(platformConf);
}
static boolean isOSGiPlatform(String platform) {
Constants.Platform p = Constants.Platform.valueOf(platform);
switch (p) {
case Felix:
case Knopflerfish:
case Equinox:
return true;
}
return false;
}
static class ClassLoaderBuilder {
protected ClassPathBuilder cpb;
protected File glassfishDir;
protected Properties ctx;
ClassLoaderBuilder(Properties ctx, ClassLoader delegate) {
this.ctx = ctx;
cpb = new ClassPathBuilder(delegate);
glassfishDir = new File(ctx.getProperty(Constants.INSTALL_ROOT_PROP_NAME));
}
void addFrameworkJars() throws IOException {
PlatformHelper.getPlatformHelper(ctx).addFrameworkJars(cpb);
}
/**
* Adds JDK tools.jar to classpath.
*/
void addJDKToolsJar() {
File jdkToolsJar = Util.getJDKToolsJar();
try {
cpb.addJar(jdkToolsJar);
} catch (IOException ioe) {
// on the mac, it happens all the time
if (logger.isLoggable(Level.FINE)) {
logger.fine("JDK tools.jar does not exist at " + jdkToolsJar);
}
}
}
public ClassLoader build() {
return cpb.create();
}
public void addLauncherJar() throws IOException {
cpb.addJar(new File(glassfishDir, "modules/glassfish.jar"));
}
public void addBootstrapApiJar() throws IOException {
cpb.addJar(new File(glassfishDir, "modules/simple-glassfish-api.jar"));
}
}
static abstract class PlatformHelper {
static synchronized PlatformHelper getPlatformHelper(Properties properties) {
Constants.Platform platform =
Constants.Platform.valueOf(properties.getProperty(Constants.PLATFORM_PROPERTY_KEY));
PlatformHelper platformHelper;
switch (platform) {
case Felix:
platformHelper = new FelixHelper();
break;
case Knopflerfish:
platformHelper = new KnopflerfishHelper();
break;
case Equinox:
platformHelper = new EquinoxHelper();
break;
case Static:
platformHelper = new StaticHelper();
break;
default:
throw new RuntimeException("Unsupported platform " + platform);
}
platformHelper.init(properties);
return platformHelper;
}
protected Properties properties;
protected File glassfishDir;
protected File domainDir;
protected File fwDir;
/**
* Location of the unified config properties file relative to the domain directory
*/
public static final String CONFIG_PROPERTIES = "config/osgi.properties";
/**
* @param properties Initial properties
*/
void init(Properties properties) {
this.properties = properties;
glassfishDir = StartupContextUtil.getInstallRoot(properties);
domainDir = StartupContextUtil.getInstanceRoot(properties);
setFwDir();
}
protected abstract void setFwDir();
/**
* Adds the jar files of the OSGi platform to the given {@link ClassPathBuilder}
*/
protected abstract void addFrameworkJars(ClassPathBuilder cpb) throws IOException;
/**
* @return platform specific configuration information
*/
protected Properties readPlatformConfiguration() throws IOException {
Properties platformConfig = new Properties();
final File configFile = getFrameworkConfigFile();
if (configFile == null) return platformConfig;
InputStream in = new FileInputStream(configFile);
try {
platformConfig.load(in);
} finally {
in.close();
}
return platformConfig;
}
protected File getFrameworkConfigFile() {
String fileName = CONFIG_PROPERTIES;
// First we search in domainDir. If it's not found there, we fall back on installDir
File f = new File(domainDir, fileName);
if (!f.exists()) {
f = new File(glassfishDir, fileName);
} else {
logger.log(Level.INFO, LogFacade.BOOTSTRAP_FMWCONF, f.getAbsolutePath());
}
return f;
}
}
static class FelixHelper extends PlatformHelper {
private static final String FELIX_HOME = "FELIX_HOME";
/**
* Home of FW installation relative to Glassfish root installation.
*/
public static final String GF_FELIX_HOME = "osgi/felix";
/**
* Location of the config properties file relative to the domain directory
*/
public static final String CONFIG_PROPERTIES = "config/osgi.properties";
@Override
protected void setFwDir() {
String fwPath = System.getenv(FELIX_HOME);
if (fwPath == null) {
// try system property, which comes from asenv.conf
fwPath = System.getProperty(FELIX_HOME,
new File(glassfishDir, GF_FELIX_HOME).getAbsolutePath());
}
fwDir = new File(fwPath);
if (!fwDir.exists()) {
throw new RuntimeException("Can't locate Felix at " + fwPath);
}
}
@Override
protected void addFrameworkJars(ClassPathBuilder cpb) throws IOException {
cpb.addJar(new File(fwDir, "bin/felix.jar"));
}
@Override
protected Properties readPlatformConfiguration() throws IOException {
// GlassFish filesystem layout does not recommend use of upper case char in file names.
// So, we can't use ${GlassFish_Platform} to generically set the cache dir.
// Hence, we set it here.
Properties platformConfig = super.readPlatformConfiguration();
platformConfig.setProperty(org.osgi.framework.Constants.FRAMEWORK_STORAGE,
new File(domainDir, "osgi-cache/felix/").getAbsolutePath());
return platformConfig;
}
}
static class EquinoxHelper extends PlatformHelper {
/* if equinox is installed under glassfish/eclipse this would be the
* glassfish/eclipse/plugins dir that contains the equinox jars
* can be null
* */
private static File pluginsDir = null;
protected void setFwDir() {
String fwPath = System.getenv("EQUINOX_HOME");
if (fwPath == null) {
fwPath = new File(glassfishDir, "osgi/equinox").getAbsolutePath();
}
fwDir = new File(fwPath);
if (!fwDir.exists()) {
throw new RuntimeException("Can't locate Equinox at " + fwPath);
}
}
@Override
protected void addFrameworkJars(ClassPathBuilder cpb) throws IOException {
// Add all the jars to classpath for the moment, since the jar name
// is not a constant.
if (pluginsDir != null) {
cpb.addGlob(pluginsDir, "org.eclipse.osgi_*.jar");
} else {
cpb.addJarFolder(fwDir);
}
}
@Override
protected Properties readPlatformConfiguration() throws IOException {
// GlassFish filesystem layout does not recommend use of upper case char in file names.
// So, we can't use ${GlassFish_Platform} to generically set the cache dir.
// Hence, we set it here.
Properties platformConfig = super.readPlatformConfiguration();
platformConfig.setProperty(org.osgi.framework.Constants.FRAMEWORK_STORAGE,
new File(domainDir, "osgi-cache/equinox/").getAbsolutePath());
return platformConfig;
}
}
static class KnopflerfishHelper extends PlatformHelper {
private static final String KF_HOME = "KNOPFLERFISH_HOME";
/**
* Home of fw installation relative to Glassfish root installation.
*/
public static final String GF_KF_HOME = "osgi/knopflerfish.org/osgi/";
protected void setFwDir() {
String fwPath = System.getenv(KF_HOME);
if (fwPath == null) {
fwPath = new File(glassfishDir, GF_KF_HOME).getAbsolutePath();
}
fwDir = new File(fwPath);
if (!fwDir.exists()) {
throw new RuntimeException("Can't locate KnopflerFish at " + fwPath);
}
}
@Override
protected void addFrameworkJars(ClassPathBuilder cpb) throws IOException {
cpb.addJar(new File(fwDir, "framework.jar"));
}
@Override
protected Properties readPlatformConfiguration() throws IOException {
// GlassFish filesystem layout does not recommend use of upper case char in file names.
// So, we can't use ${GlassFish_Platform} to generically set the cache dir.
// Hence, we set it here.
Properties platformConfig = super.readPlatformConfiguration();
platformConfig.setProperty(org.osgi.framework.Constants.FRAMEWORK_STORAGE,
new File(domainDir, "osgi-cache/knopflerfish/").getAbsolutePath());
return platformConfig;
}
}
static class StaticHelper extends PlatformHelper {
@Override
protected void setFwDir() {
// nothing to do
}
@Override
protected void addFrameworkJars(ClassPathBuilder cpb) throws IOException {
// nothing to do
}
@Override
protected File getFrameworkConfigFile() {
return null; // no config file for this platform.
}
}
}