Author: gtrasuk
Date: Mon Nov 14 14:02:14 2011
New Revision: 1201710
URL: http://svn.apache.org/viewvc?rev=1201710&view=rev
Log:
Copy and refactoring of ClassServer to serve surrogate codebase inside the
surrogate container.
Added:
river/jtsk/skunk/surrogate/src/org/apache/river/container/Shutdown.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/UUIDEncoder.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/work/BasicWorkManager.java
river/jtsk/skunk/surrogate/test/org/apache/river/container/codebase/
river/jtsk/skunk/surrogate/test/org/apache/river/container/work/
river/jtsk/skunk/surrogate/test/org/apache/river/container/work/BasicWorkManagerTest.java
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/DeploymentListener.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/MBeanRegistrar.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
river/jtsk/skunk/surrogate/src/org/apache/river/container/ShowContextToConsole.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/ShutdownListener.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/StarterServiceDeployer.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/SystemClassloaderInitializer.java
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java
river/jtsk/skunk/surrogate/testfiles/testroot/profile/default/config.xml
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java
Mon Nov 14 14:02:14 2011
@@ -48,6 +48,10 @@ public class AnnotatedClassDeployer impl
private List<DeploymentListener> deploymentListeners =
new ArrayList<DeploymentListener>();
+ public List<DeploymentListener> getDeploymentListeners() {
+ return deploymentListeners;
+ }
+
public void put(String name, Object o) {
try {
/*
@@ -90,6 +94,14 @@ public class AnnotatedClassDeployer impl
checkUnresolvedDependencies();
}
+ @Override
+ public void shutDown() {
+ for(DeploymentListener l: getDeploymentListeners()) {
+ l.shutDown();
+ }
+ }
+
+
private void checkUnresolvedDependencies() {
if (uninitializedObjects.isEmpty()) {
return;
@@ -129,6 +141,9 @@ public class AnnotatedClassDeployer impl
if (deployed.getDeployedObject() instanceof
DeploymentListener) {
deploymentListeners.add((DeploymentListener)
deployed.getDeployedObject());
}
+ if (!deployed.getShutdownMethods().isEmpty()) {
+ deploymentListeners.add(new ShutdownRunner(deployed));
+ }
deployed.setInitialized(true);
}
return true;
@@ -166,6 +181,9 @@ public class AnnotatedClassDeployer impl
if (isInitMethod(m)) {
deployed.getInitMethods().add((Method) m);
}
+ if (isShutdownMethod(m)) {
+ deployed.getShutdownMethods().add((Method) m);
+ }
if (isAnnotatedAsName(m)) {
memberSet(deployed.getDeployedObject(), m, deployed.getName());
}
@@ -209,6 +227,37 @@ public class AnnotatedClassDeployer impl
return true;
}
+ /**
+ It's a shutdown method if it is
+ <ul>
+ <li>a Method</li>
+ <li>is annotated @Shutdown</li>
+ <li>takes no parameter</li>
+ <li>returns void</li>
+ </ul>
+ @param m The method to evaluate.
+ @return
+ */
+ private boolean isShutdownMethod(Member m) {
+ AnnotatedElement annEm = (AnnotatedElement) m;
+ if (annEm.getAnnotation(Shutdown.class) == null) {
+ return false;
+ }
+ Method method = (Method) m;
+ if (method.getReturnType() != void.class) {
+ throw new
ConfigurationException(MessageNames.SHUTDOWN_METHOD_NOT_VOID,
+ m.getDeclaringClass().getName(),
+ m.getName(),
+ method.getReturnType());
+ }
+ if (method.getParameterTypes().length != 0) {
+ throw new
ConfigurationException(MessageNames.SHUTDOWN_METHOD_HAS_PARAMETERS,
+ m.getDeclaringClass().getName(),
+ m.getName());
+ }
+ return true;
+ }
+
private boolean isAnnotatedAsInjected(Member m) {
AnnotatedElement annEm = (AnnotatedElement) m;
if (annEm.getAnnotation(Injected.class) != null) {
@@ -404,14 +453,53 @@ public class AnnotatedClassDeployer impl
Field f = (Field) member;
boolean originalAccess = f.isAccessible();
f.setAccessible(true);
- f.set(target, value);
+ f.set(target, convertProperty(value, f.getType()));
f.setAccessible(originalAccess);
} else {
Method m = (Method) member;
boolean originalAccess = m.isAccessible();
m.setAccessible(true);
- m.invoke(target, value);
+ m.invoke(target, convertProperty(value, m.getParameterTypes()[0]));
m.setAccessible(originalAccess);
}
}
+
+ private Object convertProperty(Object value, Class requiredType) {
+ /* TODO: Make this a little more flexible and configurable! */
+ if (requiredType.isAssignableFrom(value.getClass())) {
+ return value;
+ }
+ if (requiredType.equals(Integer.class)
+ || requiredType.equals(int.class)) {
+ return Integer.parseInt(value.toString());
+ }
+ throw new LocalizedRuntimeException(MessageNames.BUNDLE_NAME,
MessageNames.CANT_CONVERT_EXCEPTION,
+ new Object[] {value.toString(), requiredType.toString()} );
+ }
+ private class ShutdownRunner implements DeploymentListener {
+
+ private DeployedObject deployedObject=null;
+
+ ShutdownRunner(DeployedObject o) {
+ deployedObject=o;
+ }
+
+ @Override
+ public void postInit(String name, Object object) {
+ // No action. Handled in upper level.
+ }
+
+ @Override
+ public void shutDown() {
+ for(Method m:deployedObject.getShutdownMethods()) {
+ try {
+ m.invoke(deployedObject.getDeployedObject(), new
Object[0]);
+ } catch(Throwable t) {
+ // TODO: Figure out what to do here!
+ t.printStackTrace();
+ }
+ }
+ }
+
+ }
}
Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java
(original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java Mon
Nov 14 14:02:14 2011
@@ -75,4 +75,10 @@ public class Context {
}
}
+
+ public void shutDown() {
+ for(ContextListener l:listeners) {
+ l.shutDown();
+ }
+ }
}
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java
Mon Nov 14 14:02:14 2011
@@ -47,4 +47,10 @@ public interface ContextListener {
Indicates that processing of any initialization file is complete.
*/
public void initComplete();
+
+ /**
+ Indicates that the container is shutting down, so all resources should
+ be closed and/or released.
+ */
+ public void shutDown();
}
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java
Mon Nov 14 14:02:14 2011
@@ -33,6 +33,12 @@ public class DeployedObject {
private String name;
private List<Member> unresolvedDependencies=new ArrayList<Member>();
private List<Method> initMethods=new ArrayList<Method>();
+ private List<Method> shutdownMethods=new ArrayList<Method>();
+
+ public List<Method> getShutdownMethods() {
+ return shutdownMethods;
+ }
+
private boolean initialized=false;
public boolean isInitialized() {
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/DeploymentListener.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/DeploymentListener.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/DeploymentListener.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/DeploymentListener.java
Mon Nov 14 14:02:14 2011
@@ -23,4 +23,6 @@ package org.apache.river.container;
*/
public interface DeploymentListener {
public void postInit(String name, Object object);
+
+ public void shutDown();
}
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/MBeanRegistrar.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/MBeanRegistrar.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/MBeanRegistrar.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/MBeanRegistrar.java
Mon Nov 14 14:02:14 2011
@@ -48,4 +48,9 @@ public class MBeanRegistrar implements D
public void init() {
mbeanServer=ManagementFactory.getPlatformMBeanServer();
}
+
+ @Override
+ public void shutDown() {
+
+ }
}
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
(original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
Mon Nov 14 14:02:14 2011
@@ -46,8 +46,11 @@ public class MessageNames {
BAD_CLASSPATH_EXPR="badClasspathExpression",
BAD_MEMBER_FOR_INJECTED_ANNOTATION="badMemberForInjectedAnnotation",
BAD_MEMBER_FOR_NAME_ANNOTATION="badMemberForNameAnnotation",
+ BASIC_WORK_MANAGER_INITIALIZED="basicWorkManagerInitialized",
CALLING_MAIN="callingMain",
+ CANT_CONVERT_EXCEPTION="cantConvertException",
CANT_READ_START_PROPERTIES="cantReadStartProperties",
+ CLASS_SERVER_INIT_FAILED="classServerInitFailed",
CODESOURCE_IS="codeSourceIs",
COMPLETED_SERVICE_DEPLOYMENT="completedServiceDeployment",
CONFIG_FILE="configFile",
@@ -73,6 +76,8 @@ public class MessageNames {
READING_OBJECT_ANNOTATED_MEMBER_FOUND="readingObject.annotatedMemberFound",
READING_OBJECT_NON_ANNOTATED_MEMBER_FOUND="readingObject.nonAnnotatedMemberFound",
SHOW_COMMAND_LINE_ARGUMENTS="showCommandLineArguments",
+ SHUTDOWN_METHOD_HAS_PARAMETERS="shutdownMethodHasParameters",
+ SHUTDOWN_METHOD_NOT_VOID="shutdownMethodIsntVoid",
STARTER_SERVICE_DEPLOYER_FAILED_INIT="starterServiceDeployerFailedInit",
STARTER_SERVICE_DEPLOYER_INITIALIZED="starterServiceDeployerInitialized",
STARTER_SERVICE_DEPLOYER_STARTING="starterServiceDeployerStarting",
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
Mon Nov 14 14:02:14 2011
@@ -25,8 +25,11 @@ badMemberForInjectedAnnotation=@Injected
setter method only: Member {1} on class {0} doesn't qualify.
badMemberForNameAnnotation=@Name annotation must be applied to a String field
or\
setter method only: Member {1} on class {0} doesn't qualify.
+basicWorkManagerInitialized=Basic Work Manager was initialized.
callingMain=Calling main method on class ''{0}'' with arguments {1}.
+cantConvertException=Can''t convert type ''{0}'' to ''{1}''.
cantReadStartProperties=Can''t read starter configuration file ''{0}'' in
''{1}''.
+classServerInitFailed=Class Server initialization failed.
codeSourceIs=CodeSource for service in ''{0}'' is ''{1}''.
completedServiceDeployment=Completed deployment of service in {0}.
configFile=Configuration file is ''{0}''.
@@ -55,6 +58,10 @@ readingObject.memberCount={0} members fo
readingObject.annotatedMemberFound=Member ''{0}'' is annotated @Injected.
readingObject.nonAnnotatedMemberFound=Member ''{0}'' is not annotated
@Injected.
showCommandLineArguments=Command line arguments were: {0}.
+shutdownMethodHasParameters=A method flagged as @Shutdown must take no
parameters. \
+Method ''{1}'' on class ''{0}'' has parameters.
+shutdownMethodIsntVoid=A method flagged as @Shutdown must be void return type.
\
+Method ''{1}'' on class ''{0}'' returns ''{2}''.
starterServiceDeployerFailedInit=Starter-Service deployer has failed to
initialize.
starterServiceDeployerInitialized=Starter-Service deployer named ''{0}''
completed \
initialization.
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/ShowContextToConsole.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/ShowContextToConsole.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/ShowContextToConsole.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/ShowContextToConsole.java
Mon Nov 14 14:02:14 2011
@@ -54,4 +54,9 @@ public class ShowContextToConsole implem
public void initComplete() {
init();
}
+
+ @Override
+ public void shutDown() {
+
+ }
}
Added: river/jtsk/skunk/surrogate/src/org/apache/river/container/Shutdown.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/Shutdown.java?rev=1201710&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/Shutdown.java
(added)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/Shutdown.java Mon
Nov 14 14:02:14 2011
@@ -0,0 +1,36 @@
+/*
+ * 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.river.container;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ Identifies a method which should be called when the context is being shut
down.
+ * @author trasukg
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Shutdown {
+
+}
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/ShutdownListener.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/ShutdownListener.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/ShutdownListener.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/ShutdownListener.java
Mon Nov 14 14:02:14 2011
@@ -25,10 +25,15 @@ import java.util.logging.Logger;
* @author trasukg
*/
public class ShutdownListener implements ShutdownListenerMXBean, Runnable {
+
+ @Injected
+ private Context context=null;
+
public void run() {
synchronized(this) {
try {
wait();
+ context.shutDown();
} catch (InterruptedException ex) {
Logger.getLogger(ShutdownListener.class.getName()).log(Level.SEVERE, null, ex);
}
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/StarterServiceDeployer.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/StarterServiceDeployer.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/StarterServiceDeployer.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/StarterServiceDeployer.java
Mon Nov 14 14:02:14 2011
@@ -251,7 +251,8 @@ public class StarterServiceDeployer {
new Object[] {serviceName, serviceCodeSource});
VirtualFileSystemClassLoader cl =
createServiceClassloader(serviceRoot, serviceCodeSource);
/* Create a codebase context. */
- CodebaseContext codebaseContext = codebaseHandler.createContext();
+ CodebaseContext codebaseContext =
+ codebaseHandler.createContext(serviceName);
addPlatformCodebaseJars(codebaseContext);
exportServiceCodebaseJars(serviceRoot, codebaseContext);
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/SystemClassloaderInitializer.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/SystemClassloaderInitializer.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/SystemClassloaderInitializer.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/SystemClassloaderInitializer.java
Mon Nov 14 14:02:14 2011
@@ -1,7 +1,21 @@
/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+ * 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.river.container;
/**
Modified:
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java
(original)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServer.java
Mon Nov 14 14:02:14 2011
@@ -32,13 +32,15 @@ import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
-import java.util.MissingResourceException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.river.container.Init;
import org.apache.river.container.Injected;
import org.apache.river.container.MessageNames;
+import org.apache.river.container.Shutdown;
import org.apache.river.container.work.TaskClass;
import org.apache.river.container.work.WorkManager;
@@ -101,10 +103,11 @@ import org.apache.river.container.work.W
*
*
*/
+
public class ClassServer implements CodebaseHandler {
private static final Logger logger =
- Logger.getLogger(MessageNames.BUNDLE_NAME,
ClassServer.class.getName());
+ Logger.getLogger(ClassServer.class.getName(),
MessageNames.BUNDLE_NAME);
/** Server socket to accept connections on */
private ServerSocket server;
@Injected
@@ -112,6 +115,8 @@ public class ClassServer implements Code
@Injected
private int initialPort = -1;
+ List<ClassServerCodebaseContext> contexts=new
ArrayList<ClassServerCodebaseContext>();
+
@Init
public void init() {
try {
@@ -124,14 +129,11 @@ public class ClassServer implements Code
}
});
} catch (IOException ex) {
- Logger.getLogger(ClassServer.class.getName()).log(Level.SEVERE,
null, ex);
+ logger.log(Level.SEVERE, MessageNames.CLASS_SERVER_INIT_FAILED, ex
);
+ throw new RuntimeException(ex);
}
}
- private void processConnection(Socket connectedSocket) {
- new Task(connectedSocket).start();
- }
-
private void establishServerSocket() throws IOException, SocketException {
server = new ServerSocket();
server.setReuseAddress(true);
@@ -159,7 +161,7 @@ public class ClassServer implements Code
new Runnable() {
@Override
public void run() {
- processConnection(connectedSocket);
+ processRequest(connectedSocket);
}
});
}
@@ -174,6 +176,7 @@ public class ClassServer implements Code
}
/** Close the server socket, causing the thread to terminate. */
+ @Shutdown
public synchronized void terminate() {
try {
server.close();
@@ -271,37 +274,19 @@ public class ClassServer implements Code
@Override
public CodebaseContext createContext(String appId) {
// Create a context
+ ClassServerCodebaseContext context=new
ClassServerCodebaseContext(appId);
// Assign a context prefix (url-shortened)
- throw new UnsupportedOperationException("Not supported yet.");
+ contexts.add(context);
+ return context;
}
@Override
public void destroyContext(CodebaseContext context) {
// Remove all the jar mappings.
//destroy the context.
- throw new UnsupportedOperationException("Not supported yet.");
+ contexts.remove((ClassServerCodebaseContext) context);
}
- /** Simple daemon task thread */
- private class Task extends Thread {
-
- /** Socket for the incoming request */
- private Socket sock;
-
- /** Simple constructor */
- public Task(Socket sock) {
- this.sock = sock;
- setDaemon(true);
- }
-
- /** Process the request */
- @Override
- public void run() {
- if (processRequest(sock)) {
- return;
- }
- }
- }
private static ResourceBundle resources;
private static boolean resinit = false;
@@ -441,36 +426,5 @@ public class ClassServer implements Code
return false;
}
- private static synchronized String getString(String key) {
- if (!resinit) {
- resinit = true;
- try {
- resources =
ResourceBundle.getBundle("com.sun.jini.tool.resources.classserver");
- } catch (MissingResourceException e) {
- logger.log(Level.WARNING, "missing resource bundle {0}",
- "com.sun.jini.tool.resources.classserver");
- }
- }
- if (resources != null) {
- try {
- return resources.getString(key);
- } catch (MissingResourceException e) {
- }
- }
- return null;
- }
- private static void print(String key, String val) {
- String fmt = getString(key);
- if (fmt == null) {
- fmt = "no text found: \"" + key + "\" {0}";
- }
- logger.log(Level.FINE, key, new String[]{val});
- }
-
- private static void print(String key, String[] vals) {
- String fmt = getString(key);
-
- logger.log(Level.INFO, key, vals);
- }
}
Added:
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java?rev=1201710&view=auto
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java
(added)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/ClassServerCodebaseContext.java
Mon Nov 14 14:02:14 2011
@@ -0,0 +1,56 @@
+/*
+ * 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.river.container.codebase;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.apache.commons.vfs.FileObject;
+import org.apache.river.container.LocalizedRuntimeException;
+import org.apache.river.container.MessageNames;
+
+/**
+ *
+ * @author trasukg
+ */
+public class ClassServerCodebaseContext implements CodebaseContext {
+
+ String appId = null;
+
+ ClassServerCodebaseContext(String appId) {
+ this.appId = appId;
+ }
+
+ @Override
+ public String getAppId() {
+ return appId;
+ }
+
+ @Override
+ public void addFile(FileObject file) {
+
+ }
+
+ @Override
+ public URL[] getCodebaseAnnotation() {
+ try {
+ return new URL[] { new URL("http://unknown.jar") };
+ } catch (MalformedURLException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
Added:
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/UUIDEncoder.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/UUIDEncoder.java?rev=1201710&view=auto
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/UUIDEncoder.java
(added)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/codebase/UUIDEncoder.java
Mon Nov 14 14:02:14 2011
@@ -0,0 +1,32 @@
+/*
+ * 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.river.container.codebase;
+
+import java.util.UUID;
+
+/**
+ * Class encodes a 128-bit UUID into a shortened form suitable for use
+ as a url.
+ * @author trasukg
+ */
+public class UUIDEncoder {
+ public String encode(UUID uuid) {
+ return uuid.toString();
+ }
+}
Added:
river/jtsk/skunk/surrogate/src/org/apache/river/container/work/BasicWorkManager.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/work/BasicWorkManager.java?rev=1201710&view=auto
==============================================================================
---
river/jtsk/skunk/surrogate/src/org/apache/river/container/work/BasicWorkManager.java
(added)
+++
river/jtsk/skunk/surrogate/src/org/apache/river/container/work/BasicWorkManager.java
Mon Nov 14 14:02:14 2011
@@ -0,0 +1,79 @@
+/*
+ * 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.river.container.work;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.logging.Logger;
+import org.apache.river.container.Init;
+import org.apache.river.container.MessageNames;
+import org.apache.river.container.Shutdown;
+
+/**
+
+A Basic implementation of WorkManager that runs the work threads through
+a ThreadPoolExecutor.
+
+ * @author trasukg
+ */
+public class BasicWorkManager implements WorkManager {
+ private static final Logger
log=Logger.getLogger(BasicWorkManager.class.getName(),
MessageNames.BUNDLE_NAME);
+
+ ExecutorService executor = Executors.newCachedThreadPool();
+
+ @Override
+ public void queueTask(TaskClass taskClass, ClassLoader contextClassLoader,
Runnable task) {
+ ClassLoader classLoaderToUse =
+ contextClassLoader != null ? contextClassLoader :
Thread.currentThread().getContextClassLoader();
+ executor.execute(new TaskHolder(task, classLoaderToUse));
+ }
+
+ private class TaskHolder implements Runnable {
+
+ Runnable task = null;
+ ClassLoader contextClassLoader = null;
+ ClassLoader originalClassLoader = null;
+
+ TaskHolder(Runnable task, ClassLoader contextClassLoader) {
+ this.task = task;
+ this.contextClassLoader = contextClassLoader;
+ }
+
+ @Override
+ public void run() {
+ originalClassLoader =
Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ try {
+ task.run();
+ } finally {
+
Thread.currentThread().setContextClassLoader(originalClassLoader);
+ }
+ }
+ }
+
+ @Init
+ public void init() {
+ log.info(MessageNames.BASIC_WORK_MANAGER_INITIALIZED);
+ }
+
+ @Shutdown
+ public void shutdown() {
+ executor.shutdownNow();
+ }
+}
Added:
river/jtsk/skunk/surrogate/test/org/apache/river/container/work/BasicWorkManagerTest.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/test/org/apache/river/container/work/BasicWorkManagerTest.java?rev=1201710&view=auto
==============================================================================
---
river/jtsk/skunk/surrogate/test/org/apache/river/container/work/BasicWorkManagerTest.java
(added)
+++
river/jtsk/skunk/surrogate/test/org/apache/river/container/work/BasicWorkManagerTest.java
Mon Nov 14 14:02:14 2011
@@ -0,0 +1,71 @@
+/*
+ * 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.river.container.work;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author trasukg
+ */
+public class BasicWorkManagerTest {
+
+ public BasicWorkManagerTest() {
+ }
+
+ BasicWorkManager UUT=new BasicWorkManager();
+
+ @Test
+ public void testNullContextClassLoader() {
+ Harness h=new Harness();
+ UUT.queueTask(TaskClass.SYSTEM_TASK, null, h);
+ waitHarness(4000,h);
+ assertEquals("Didn't use current context classloader.",
+ Thread.currentThread().getContextClassLoader(), h.cl);
+ }
+
+ private void waitHarness(long time, Harness h) {
+ long start=System.currentTimeMillis();
+ while ( !h.done && System.currentTimeMillis() - start < time) {
+ Thread.yield();
+ }
+ if (System.currentTimeMillis() - start >= time) {
+ fail("Harness task did not run.");
+ }
+ }
+
+ private class Harness implements Runnable {
+ ClassLoader cl=null;
+ boolean done=false;
+ String threadName=null;
+
+ @Override
+ public void run() {
+ cl=Thread.currentThread().getContextClassLoader();
+ threadName=Thread.currentThread().getName();
+ done=true;
+ }
+ }
+
+}
Modified:
river/jtsk/skunk/surrogate/testfiles/testroot/profile/default/config.xml
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/testfiles/testroot/profile/default/config.xml?rev=1201710&r1=1201709&r2=1201710&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/testfiles/testroot/profile/default/config.xml
(original)
+++ river/jtsk/skunk/surrogate/testfiles/testroot/profile/default/config.xml
Mon Nov 14 14:02:14 2011
@@ -25,6 +25,7 @@
<cfg:discovery-context name="default">
<cfg:group>TEST</cfg:group>
</cfg:discovery-context>
+ <cfg:component class="org.apache.river.container.work.BasicWorkManager"/>
<cfg:component
class="org.apache.river.container.codebase.DummyCodebaseHandler"/>
<cfg:component class="org.apache.river.container.StarterServiceDeployer"/>
<cfg:component class="org.apache.river.container.ShowContextToConsole"/>