/*
* 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 com.sun.jini.test.impl.start;
import java.rmi.RemoteException;
import java.rmi.activation.Activatable;
import java.rmi.activation.ActivationID;
import java.rmi.activation.ActivationException;
import java.rmi.MarshalledObject;
import com.sun.jini.config.Config;
import com.sun.jini.test.impl.start.TestService;
import com.sun.jini.start.LifeCycle;
import net.jini.config.Configuration;
import net.jini.config.ConfigurationException;
import net.jini.config.ConfigurationProvider;
import net.jini.export.Exporter;
import net.jini.export.ProxyAccessor;
import net.jini.id.Uuid;
import net.jini.id.UuidFactory;
import net.jini.jeri.BasicJeriExporter;
import net.jini.jeri.BasicILFactory;
import net.jini.jeri.tcp.TcpServerEndpoint;
import java.io.File;
import java.io.IOException;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.SecureClassLoader;
import java.util.*;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
/**
* Activatable implementation of the TestService interface.
*/
public class TestServiceImpl implements TestService, ProxyAccessor {
private static volatile int staticInt = 0;
private Uuid uuid;
private TestService serverStub = null;
private static final String TEST_SERVICE = "com.sun.jini.testservice";
public Object getProxy() { return serverStub; }
// Activation constructor
public TestServiceImpl(ActivationID activationID, MarshalledObject data)
throws Exception
{
init((String[])data.get());
}
//
public TestServiceImpl(String[] configArgs, LifeCycle lc)
throws Exception
{
init(configArgs);
}
private void init(String[] configArgs) throws Exception {
final Configuration config =
ConfigurationProvider.getInstance(configArgs);
LoginContext loginContext = (LoginContext) config.getEntry(
TEST_SERVICE, "loginContext", LoginContext.class, null);
if (loginContext != null) {
doInitWithLogin(config, loginContext);
} else {
doInit(config);
}
}
private void doInitWithLogin(final Configuration config,
LoginContext loginContext) throws Exception
{
loginContext.login();
try {
Subject.doAsPrivileged(
loginContext.getSubject(),
new PrivilegedExceptionAction() {
public Object run() throws Exception {
doInit(config);
return null;
}
},
null);
} catch (PrivilegedActionException e) {
try {
loginContext.logout();
} catch (LoginException le) {
System.out.println("Trouble logging out" + le);
}
throw e.getException();
}
}
/** Initialization common to both activatable and transient instances. */
private void doInit(Configuration config) throws Exception {
uuid = net.jini.id.UuidFactory.generate();
Exporter exporter = (Exporter) Config.getNonNullEntry(
config, TEST_SERVICE, "exporter", Exporter.class,
new BasicJeriExporter(
TcpServerEndpoint.getInstance(0), new BasicILFactory(), false, true));
System.out.println("service exporter is: "
+ exporter);
// Export server instance and get its reference
serverStub = (TestService)exporter.export(this);
System.out.println("Service stub is: " + serverStub);
// Store class loader ref in shared map
TestServiceSharedMap.storeClassLoader(
uuid, this.getClass().getClassLoader());
}
// inherit javadoc
// used by SecurityTest
public byte[] loadFile(File file)
throws RemoteException, FileNotFoundException, IOException
{
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int nextByte;
try {
while ((nextByte = fis.read()) != -1) {
bos.write(nextByte);
}
} catch (EOFException eofe) {
eofe.printStackTrace(System.err);
}
fis.close();
bos.flush();
return bos.toByteArray();
}
// inherit javadoc
// used by CodebaseTest & ClasspathTest
public Object loadClass(String className)
throws RemoteException, ClassNotFoundException,
IllegalAccessException, InstantiationException
{
Class newClass = Class.forName(className);
return newClass.newInstance();
}
// inherit javadoc
// used by ClasspathTest
public void setCommonStaticVariable(int newValue) throws RemoteException {
System.out.println("TestServiceImpl.setCommonStaticVariable: "
+ "class path is " + System.getProperty("java.class.path"));
TestServiceDummyClass0.commonStaticInt = newValue;
}
// inherit javadoc
// used by ClasspathTest
public int getCommonStaticVariable() throws RemoteException {
System.out.println("TestServiceImpl.getCommonStaticVariable: "
+ "class path is " + System.getProperty("java.class.path"));
return TestServiceDummyClass0.commonStaticInt;
}
// inherit javadoc
// used by ClasspathTest
public void setLocalStaticVariable(int newValue) throws RemoteException {
TestServiceImpl.staticInt = newValue;
}
// inherit javadoc
// used by ClasspathTest
public int getLocalStaticVariable() throws RemoteException {
return TestServiceImpl.staticInt;
}
// inherit javadoc
// used by ClassLoaderTest
public boolean compareSiblingClassLoaderHierarchy(Uuid other)
throws RemoteException
{
boolean result = false;
try {
ClassLoader thisClassLoader =
(ClassLoader) TestServiceSharedMap.getClassLoader(uuid);
ClassLoader otherClassLoader =
(ClassLoader) TestServiceSharedMap.getClassLoader(other);
ArrayList thisLoaders = new ArrayList();
ArrayList otherLoaders = new ArrayList();
getClassLoaderTree(thisClassLoader, thisLoaders);
System.out.println("This service's class loaders: " + thisLoaders);
getClassLoaderTree(otherClassLoader, otherLoaders);
System.out.println("Other service's class loaders: " + otherLoaders);
List thisCommon = thisLoaders.subList(0, thisLoaders.size()-2);
List otherCommon = otherLoaders.subList(0, otherLoaders.size()-2);
if (thisClassLoader != null &&
otherClassLoader != null &&
thisLoaders.size() == otherLoaders.size() &&
thisCommon.containsAll(otherCommon) &&
!thisClassLoader.equals(otherClassLoader))
{
result = true;
}
} catch (Exception e) {
System.out.println("TestServiceImpl.getClassLoaderHierarchy: "
+ "unexpected exception");
e.printStackTrace(System.out);
}
return result;
}
// used by compareToClassLoaderHierarchy()
private void getClassLoaderTree(ClassLoader c, List l) {
if (c != null) {
getClassLoaderTree(c.getParent(), l);
}
l.add(c);
}
public Uuid getUuid() throws RemoteException {
return uuid;
}
}