/*
 * 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.outrigger.leasing;

// java classes
import java.rmi.RemoteException;
import java.rmi.MarshalledObject;
import java.io.Serializable;
import java.io.ObjectStreamException;

// jini classes
import net.jini.core.event.RemoteEvent;
import net.jini.core.event.RemoteEventListener;
import net.jini.core.event.EventRegistration;
import net.jini.core.event.UnknownEventException;
import net.jini.core.entry.Entry;

import net.jini.config.Configuration;
import net.jini.config.ConfigurationException;
import net.jini.export.Exporter;
import net.jini.security.TrustVerifier;
import net.jini.security.proxytrust.ServerProxyTrust;

import com.sun.jini.proxy.BasicProxyTrustVerifier;

import com.sun.jini.qa.harness.QAConfig;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Listener that calls notifyAll on itself
 */
public class LeasedSpaceListener
    implements RemoteEventListener, ServerProxyTrust, Serializable
{
    private static Logger logger = Logger.getLogger("com.sun.jini.qa.harness");
    private boolean received = false;
    private final Object proxy;

    public LeasedSpaceListener(Configuration c) throws RemoteException {
	try {
	    Exporter exporter = QAConfig.getDefaultExporter();
	    if (c instanceof com.sun.jini.qa.harness.QAConfiguration) {
		exporter =
		(Exporter) c.getEntry("test", 
				      "outriggerListenerExporter",
				      Exporter.class);
	    }
	    proxy = exporter.export(this);
	} catch (ConfigurationException e) {
	    throw new RemoteException("Bad configuration", e);
	}
    }

    public Object writeReplace() throws ObjectStreamException {
        return proxy;
    }

    public TrustVerifier getProxyVerifier() {
	return new BasicProxyTrustVerifier(proxy);
    }

    public void notify(RemoteEvent theEvent)
            throws UnknownEventException, RemoteException {
        // Perform logging outside the synchronized block so we don't affect
        // timing.
        java.util.Date date = new java.util.Date();
        synchronized (this){
            received = true;
            this.notifyAll();
        }
        logger.log(Level.INFO, "notify called at {0}", date);
    }

    /**
     * @return the received
     */
    public synchronized boolean isReceived() {
        return received;
    }

    /**
     * @param received the received to set
     */
    public synchronized void setReceived(boolean received) {
        this.received = received;
    }
}

@@ -1543,16 +1543,215 @@
 Config;%0A
+import java.io.WriteAbortedException;%0Aimport java.rmi.server.ExportException;%0Aimport java.security.AccessControlContext;%0Aimport java.security.AccessController;%0Aimport java.security.PrivilegedAction;%0A
 import j
@@ -2095,14 +2095,8 @@
 ate 
-final 
 Obje
@@ -2104,16 +2104,101 @@
 t proxy;
+%0A    private final Exporter exporter;%0A    private final AccessControlContext context;
 %0A%0A    pu
@@ -2515,140 +2515,947 @@
   %7D%0A
-%09    proxy = exporter.export(this);%0A%09%7D catch (ConfigurationException e) %7B%0A%09    throw new RemoteException(%22Bad configuration%22, e);%0A%09%7D
+            this.exporter = exporter;%0A            context = AccessController.getContext();%0A%09    // Proxy was originally exported here, allowing %22this%22 to escape.%0A%09%7D catch (ConfigurationException e) %7B%0A%09    throw new RemoteException(%22Bad configuration%22, e);%0A%09%7D%0A    %7D%0A    %0A    private synchronized Object getProxy()%7B%0A        if (proxy == null) %7B %0A            proxy = AccessController.doPrivileged(new PrivilegedAction%3CObject%3E()%7B%0A%0A                @Override%0A                public Object run() %7B%0A                    try %7B%0A                        return exporter.export(LeasedSpaceListener.this);%0A                    %7D catch (ExportException ex) %7B%0A                        String message = %22Proxy export failed for LeaseListener%22;%0A                        logger.log(Level.WARNING, message , ex);%0A                        return null;%0A                    %7D%0A                %7D%0A                %0A            %7D, context);%0A        %7D%0A        return proxy;
 %0A   
@@ -3529,37 +3529,42 @@
 %0A        return 
-p
+getP
 roxy
+()
 ;%0A    %7D%0A%0A    pub
@@ -3638,21 +3638,26 @@
 erifier(
-p
+getP
 roxy
+()
 );%0A    %7D
@@ -4068,16 +4068,26 @@
 %7D%22, date
+.getTime()
 );%0A    %7D

Increase logging verbosity and fix "this" escaping in constructor caused by export performed during construction.