SLING-8495 - Make FSClassLoader its cache location root directory configurable
diff --git a/src/main/java/org/apache/sling/commons/fsclassloader/impl/CacheLocationUtils.java b/src/main/java/org/apache/sling/commons/fsclassloader/impl/CacheLocationUtils.java
new file mode 100644
index 0000000..1318522
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/fsclassloader/impl/CacheLocationUtils.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.sling.commons.fsclassloader.impl;
+
+import java.io.File;
+
+import org.apache.commons.lang3.StringUtils;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Utils to acquire file system cache root directory based on configuration
+ */
+public class CacheLocationUtils {
+
+ private CacheLocationUtils() {
+ }
+
+ public static File getRootDir(final BundleContext context, final FSClassLoaderComponentConfig config) {
+ String cacheLocation = config.fsclassloader_fileSystemCompiledScriptsCacheLocation();
+ if (StringUtils.isBlank(cacheLocation))
+ return new File(context.getDataFile(""), "classes");
+ else
+ return new File(cacheLocation);
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderComponentConfig.java b/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderComponentConfig.java
new file mode 100644
index 0000000..dfee0a1
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderComponentConfig.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.sling.commons.fsclassloader.impl;
+
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+/**
+ * {@code FSClassLoaderComponentConfig} Describes the declarative services description for the FileSystem Class Loader component.
+ */
+@ObjectClassDefinition(
+ name = "FileSystem Class Loader",
+ description = "Uses the file system to store and read class files from."
+)
+@interface FSClassLoaderComponentConfig {
+
+ /**
+ * Location of the filesystem compiled scripts cache
+ */
+ @AttributeDefinition(
+ name = "Location of the filesystem compiled scripts cache",
+ description = "Controls where the filesystem compiled scripts cache is stored. When the value "
+ + "is set to null (default) the cache is stored on the bundle persistent "
+ + "storage area."
+ )
+ String fsclassloader_fileSystemCompiledScriptsCacheLocation();
+}
diff --git a/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderMBeanImpl.java b/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderMBeanImpl.java
index d9afe3c..2db387d 100644
--- a/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderMBeanImpl.java
+++ b/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderMBeanImpl.java
@@ -30,7 +30,6 @@
import java.util.Map;
import org.apache.sling.commons.fsclassloader.FSClassLoaderMBean;
-import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,13 +37,13 @@
* Implementation of the FSClassLoaderMBean interface
*/
public class FSClassLoaderMBeanImpl implements FSClassLoaderMBean {
- private final BundleContext context;
+ private final File root;
private final FSClassLoaderProvider fsClassLoaderProvider;
private static final Logger log = LoggerFactory.getLogger(FSClassLoaderMBeanImpl.class);
- public FSClassLoaderMBeanImpl(final FSClassLoaderProvider fsClassLoaderProvider, final BundleContext context) {
+ public FSClassLoaderMBeanImpl(final FSClassLoaderProvider fsClassLoaderProvider, final File root) {
this.fsClassLoaderProvider = fsClassLoaderProvider;
- this.context = context;
+ this.root = root;
}
/*
@@ -76,7 +75,6 @@
Collection<String> scripts = new HashSet<String>();
try {
Map<String, ScriptFiles> s = new LinkedHashMap<String, ScriptFiles>();
- File root = new File(context.getDataFile(""), "classes");
if (root != null) {
FSClassLoaderWebConsole.readFiles(root, root, s);
}
@@ -106,7 +104,7 @@
*/
@Override
public String getFSClassLoaderRoot() {
- return new File(context.getDataFile(""), "classes").getAbsolutePath();
+ return root.getAbsolutePath();
}
}
diff --git a/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java b/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java
index 5151ee2..83e2270 100644
--- a/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java
+++ b/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java
@@ -53,6 +53,7 @@
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ServiceScope;
+import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,11 +63,15 @@
*
*/
@Component(service = ClassLoaderWriter.class, scope = ServiceScope.BUNDLE,
+ configurationPid = FSClassLoaderProvider.SHARED_CONFIGURATION_PID,
property = {
Constants.SERVICE_RANKING + ":Integer=100"
})
+@Designate(ocd = FSClassLoaderComponentConfig.class)
public class FSClassLoaderProvider implements ClassLoaderWriter {
+ public static final String SHARED_CONFIGURATION_PID = "org.apache.sling.commons.fsclassloader.impl.FSClassLoaderProvider";
+
private static final String LISTENER_FILTER = "(" + Constants.OBJECTCLASS + "="
+ ClassLoaderWriterListener.class.getName() + ")";
@@ -102,10 +107,10 @@
* @throws MalformedObjectNameException
*/
@Activate
- protected void activate(final ComponentContext componentContext)
+ protected void activate(final ComponentContext componentContext, final FSClassLoaderComponentConfig config)
throws MalformedURLException, InvalidSyntaxException, MalformedObjectNameException {
// get the file root
- this.root = new File(componentContext.getBundleContext().getDataFile(""), "classes");
+ this.root = CacheLocationUtils.getRootDir(componentContext.getBundleContext(), config);
this.root.mkdirs();
this.rootURL = this.root.toURI().toURL();
this.callerBundle = componentContext.getUsingBundle();
@@ -147,7 +152,7 @@
mbeanProps.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
mbeanProps.put("jmx.objectname", new ObjectName("org.apache.sling.classloader", jmxProps));
mbeanRegistration = componentContext.getBundleContext().registerService(FSClassLoaderMBean.class.getName(),
- new FSClassLoaderMBeanImpl(this, componentContext.getBundleContext()), mbeanProps);
+ new FSClassLoaderMBeanImpl(this, this.root), mbeanProps);
}
/**
diff --git a/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderWebConsole.java b/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderWebConsole.java
index 6f56b21..ba34035 100644
--- a/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderWebConsole.java
+++ b/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderWebConsole.java
@@ -50,6 +50,7 @@
* and Class files.
*/
@Component(service = Servlet.class,
+ configurationPid = FSClassLoaderProvider.SHARED_CONFIGURATION_PID,
property = {
"service.description=Web Console for the FileSystem Class Loader",
"service.vendor=The Apache Software Foundation",
@@ -93,9 +94,9 @@
* @throws MalformedURLException
*/
@Activate
- protected void activate(final ComponentContext componentContext) throws MalformedURLException {
+ protected void activate(final ComponentContext componentContext, final FSClassLoaderComponentConfig config) throws MalformedURLException {
// get the file root
- root = new File(componentContext.getBundleContext().getDataFile(""), "classes");
+ this.root = CacheLocationUtils.getRootDir(componentContext.getBundleContext(), config);
}
/*