8009531: Crash when redefining class with annotated method
Summary: Add code to annotated methods and command line flags to the tests to verify bug above
Reviewed-by: acorn, sspitsyn, dcubed, dholmes, alanb
/*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4882798
* @summary multi-thread test to exercise sync and contention for removes to transformer registry
* @author Gabriel Adauto, Wily Technology
*
* @run build TransformerManagementThreadRemoveTests
* @run shell MakeJAR.sh redefineAgent
* @run main/othervm -javaagent:redefineAgent.jar TransformerManagementThreadRemoveTests TransformerManagementThreadRemoveTests
*/
import java.util.*;
public class TransformerManagementThreadRemoveTests
extends TransformerManagementThreadAddTests
{
/**
* Constructor for TransformerManagementThreadRemoveTests.
* @param name
*/
public TransformerManagementThreadRemoveTests(String name)
{
super(name);
}
public static void
main (String[] args)
throws Throwable {
ATestCaseScaffold test = new TransformerManagementThreadRemoveTests(args[0]);
test.runTest();
}
protected final void
doRunTest()
throws Throwable {
testMultiThreadAddsAndRemoves();
}
public void
testMultiThreadAddsAndRemoves()
{
int size = TOTAL_THREADS + REMOVE_THREADS;
ArrayList threadList = new ArrayList(size);
for (int i = MIN_TRANS; i <= MAX_TRANS; i++)
{
int index = i - MIN_TRANS;
threadList.add(new TransformerThread("Trans"+prettyNum(index,2), i));
}
int factor = (int)Math.floor(TOTAL_THREADS / REMOVE_THREADS);
for (int i = 0; i < REMOVE_THREADS; i++)
{
threadList.add(factor * i, new RemoveThread("Remove"+i));
}
Thread[] threads = (Thread[])threadList.toArray(new Thread[size]);
setExecThread(new ExecuteTransformersThread());
getExecThread().start();
for (int i = threads.length - 1; i >= 0; i--)
{
threads[i].start();
}
while (!testCompleted())
{
// Effective Java - Item 51: Don't depend on the thread scheduler
// Use sleep() instead of yield().
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
assertTrue(finalCheck());
//printTransformers();
}
/**
* Method removeTransformer.
*/
private void
removeTransformer(Thread t)
{
ThreadTransformer tt = null;
synchronized (fAddedTransformers)
{
int size = fAddedTransformers.size();
if (size > 0)
{
int choose = (int)Math.floor(Math.random() * size);
tt = (ThreadTransformer)fAddedTransformers.remove(choose);
}
//System.out.println("removed("+tt+") size("+size+") chose("+choose+") by("+t+")");
}
if (tt != null)
{
getInstrumentation().removeTransformer(tt);
}
}
private class
RemoveThread
extends Thread
{
RemoveThread(String name)
{
super(name);
}
public void
run()
{
while (!threadsDone())
{
removeTransformer(RemoveThread.this);
}
}
}
}