From 711d7908c59e9fb9016fac15b0acdbe5b3640da0 Mon Sep 17 00:00:00 2001 From: August Shi Date: Mon, 16 Sep 2019 17:42:52 -0500 Subject: [PATCH 1/2] Removing shuffling for annotations, as it seems specifications for annotations do not explicitly state that order does not matter --- nondex-core/src/main/java/java/lang/Class.java | 4 ++-- nondex-core/src/main/java/java/lang/reflect/Field.java | 4 ++-- nondex-core/src/main/java/java/lang/reflect/Method.java | 8 ++------ 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/nondex-core/src/main/java/java/lang/Class.java b/nondex-core/src/main/java/java/lang/Class.java index 2fc0012a..cdec5497 100644 --- a/nondex-core/src/main/java/java/lang/Class.java +++ b/nondex-core/src/main/java/java/lang/Class.java @@ -3338,7 +3338,7 @@ public A[] getAnnotationsByType(Class annotationClass) * @since 1.5 */ public Annotation[] getAnnotations() { - return edu.illinois.nondex.shuffling.ControlNondeterminism.shuffle(AnnotationParser.toArray(annotationData().annotations)); + return AnnotationParser.toArray(annotationData().annotations); } /** @@ -3369,7 +3369,7 @@ public A[] getDeclaredAnnotationsByType(Class annotati * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { - return edu.illinois.nondex.shuffling.ControlNondeterminism.shuffle(AnnotationParser.toArray(annotationData().declaredAnnotations)); + return AnnotationParser.toArray(annotationData().declaredAnnotations); } // annotation data that might get invalidated when JVM TI RedefineClasses() is called diff --git a/nondex-core/src/main/java/java/lang/reflect/Field.java b/nondex-core/src/main/java/java/lang/reflect/Field.java index 832b6d88..6e243bc8 100644 --- a/nondex-core/src/main/java/java/lang/reflect/Field.java +++ b/nondex-core/src/main/java/java/lang/reflect/Field.java @@ -1123,14 +1123,14 @@ public T getAnnotation(Class annotationClass) { public T[] getAnnotationsByType(Class annotationClass) { Objects.requireNonNull(annotationClass); - return edu.illinois.nondex.shuffling.ControlNondeterminism.shuffle(AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass)); + return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass); } /** * {@inheritDoc} */ public Annotation[] getDeclaredAnnotations() { - return edu.illinois.nondex.shuffling.ControlNondeterminism.shuffle(AnnotationParser.toArray(declaredAnnotations())); + return AnnotationParser.toArray(declaredAnnotations()); } private transient Map, Annotation> declaredAnnotations; diff --git a/nondex-core/src/main/java/java/lang/reflect/Method.java b/nondex-core/src/main/java/java/lang/reflect/Method.java index 02b4ef60..7b0e89d5 100644 --- a/nondex-core/src/main/java/java/lang/reflect/Method.java +++ b/nondex-core/src/main/java/java/lang/reflect/Method.java @@ -612,7 +612,7 @@ public T getAnnotation(Class annotationClass) { * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { - return edu.illinois.nondex.shuffling.ControlNondeterminism.shuffle(super.getDeclaredAnnotations()); + return super.getDeclaredAnnotations(); } /** @@ -621,11 +621,7 @@ public Annotation[] getDeclaredAnnotations() { */ @Override public Annotation[][] getParameterAnnotations() { - Annotation[][] anns = sharedGetParameterAnnotations(parameterTypes, parameterAnnotations); - for (int i = 0;i Date: Wed, 18 Sep 2019 19:00:54 -0500 Subject: [PATCH 2/2] Removing annotation shuffling from the instrumentation logic too, as well as modifying tests so they do not expect shuffling annotations --- .../instr/ClassVisitorShufflingAdder.java | 5 -- .../instr/HashIteratorShufflerASMDump.java | 1 - .../nondex/instr/MethodShufflingAdder.java | 51 ---------------- .../edu/illinois/nondex/core/ClassTest.java | 13 ----- .../illinois/nondex/core/ClassTestHelper.java | 14 +---- .../edu/illinois/nondex/core/FieldTest.java | 58 ------------------- .../edu/illinois/nondex/core/MethodTest.java | 10 ---- .../illinois/nondex/core/TestAnnotation1.java | 35 ----------- .../illinois/nondex/core/TestAnnotation2.java | 36 ------------ .../illinois/nondex/core/TestAnnotation3.java | 36 ------------ .../illinois/nondex/core/TestAnnotation4.java | 36 ------------ 11 files changed, 1 insertion(+), 294 deletions(-) delete mode 100644 nondex-test/src/test/java/edu/illinois/nondex/core/FieldTest.java delete mode 100644 nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation1.java delete mode 100644 nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation2.java delete mode 100644 nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation3.java delete mode 100644 nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation4.java diff --git a/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/ClassVisitorShufflingAdder.java b/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/ClassVisitorShufflingAdder.java index 0835cd49..a068eb4e 100644 --- a/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/ClassVisitorShufflingAdder.java +++ b/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/ClassVisitorShufflingAdder.java @@ -50,11 +50,6 @@ public class ClassVisitorShufflingAdder extends ClassVisitor { apisReturningShufflableArrays.add("java/lang/Class.getDeclaredFields"); apisReturningShufflableArrays.add("java/lang/Class.getDeclaredMethods"); apisReturningShufflableArrays.add("java/lang/Class.getDeclaredConstructors"); - apisReturningShufflableArrays.add("java/lang/Class.getAnnotations"); - apisReturningShufflableArrays.add("java/lang/Class.getDeclaredAnnotations"); - - apisReturningShufflableArrays.add("java/lang/reflect/Field.getAnnotationsByType"); - apisReturningShufflableArrays.add("java/lang/reflect/Field.getDeclaredAnnotations"); apisReturningShufflableArrays.add("java/io/File.list"); apisReturningShufflableArrays.add("java/io/File.listFiles"); diff --git a/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/HashIteratorShufflerASMDump.java b/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/HashIteratorShufflerASMDump.java index 309caa19..32895dd4 100644 --- a/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/HashIteratorShufflerASMDump.java +++ b/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/HashIteratorShufflerASMDump.java @@ -1,6 +1,5 @@ package edu.illinois.nondex.instr; -import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Label; diff --git a/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/MethodShufflingAdder.java b/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/MethodShufflingAdder.java index dacc838e..23f265f7 100644 --- a/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/MethodShufflingAdder.java +++ b/nondex-instrumentation/src/main/java/edu/illinois/nondex/instr/MethodShufflingAdder.java @@ -70,57 +70,6 @@ public void visitInsn(int opcode) { } }; } - if ("getDeclaredAnnotations".equals(name)) { - return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) { - @Override - public void visitInsn(int opcode) { - if (opcode == Opcodes.ARETURN) { - super.visitMethodInsn(Opcodes.INVOKESTATIC, - "edu/illinois/nondex/shuffling/ControlNondeterminism", - "shuffle", "([Ljava/lang/Object;)[Ljava/lang/Object;", false); - super.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/annotation/Annotation;"); - } - super.visitInsn(opcode); - } - }; - } - if ("getParameterAnnotations".equals(name)) { - return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) { - @Override - public void visitInsn(int opcode) { - if (opcode == Opcodes.ARETURN) { - super.visitVarInsn(Opcodes.ASTORE, 1); - super.visitInsn(Opcodes.ICONST_0); - super.visitVarInsn(Opcodes.ISTORE, 2); - Label l0 = new Label(); - super.visitLabel(l0); - super.visitFrame(Opcodes.F_APPEND, 2, new Object[]{ - "[[Ljava/lang/annotation/Annotation;", Opcodes.INTEGER}, 0, null); - super.visitVarInsn(Opcodes.ILOAD, 2); - super.visitVarInsn(Opcodes.ALOAD, 1); - super.visitInsn(Opcodes.ARRAYLENGTH); - Label l1 = new Label(); - super.visitJumpInsn(Opcodes.IF_ICMPGE, l1); - super.visitVarInsn(Opcodes.ALOAD, 1); - super.visitVarInsn(Opcodes.ILOAD, 2); - super.visitVarInsn(Opcodes.ALOAD, 1); - super.visitVarInsn(Opcodes.ILOAD, 2); - super.visitInsn(Opcodes.AALOAD); - super.visitMethodInsn(Opcodes.INVOKESTATIC, - "edu/illinois/nondex/shuffling/ControlNondeterminism", - "shuffle", "([Ljava/lang/Object;)[Ljava/lang/Object;", false); - super.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/annotation/Annotation;"); - super.visitInsn(Opcodes.AASTORE); - super.visitIincInsn(2, 1); - super.visitJumpInsn(Opcodes.GOTO, l0); - super.visitLabel(l1); - super.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); - super.visitVarInsn(Opcodes.ALOAD, 1); - } - super.visitInsn(opcode); - } - }; - } return super.visitMethod(access, name, desc, signature, exceptions); } diff --git a/nondex-test/src/test/java/edu/illinois/nondex/core/ClassTest.java b/nondex-test/src/test/java/edu/illinois/nondex/core/ClassTest.java index d239e8e1..1ee1b49e 100644 --- a/nondex-test/src/test/java/edu/illinois/nondex/core/ClassTest.java +++ b/nondex-test/src/test/java/edu/illinois/nondex/core/ClassTest.java @@ -41,9 +41,6 @@ public class ClassTest { @Before public void setUp() { - // TODO: pick a class with annotations and test: - // clazz.getAnnotations(); - // clazz.getDeclaredAnnotations(); clazz = ClassTestHelper.class; } @@ -81,14 +78,4 @@ public void getMethodsTest() { public void getDeclaredMethodsTest() { assertThat(clazz.getDeclaredMethods(), not(equalTo(clazz.getDeclaredMethods()))); } - - @Test - public void getAnnotationsTest() { - assertThat(clazz.getAnnotations(), not(equalTo(clazz.getAnnotations()))); - } - - @Test - public void getDeclaredAnnotationsTest() { - assertThat(clazz.getDeclaredAnnotations(), not(equalTo(clazz.getDeclaredAnnotations()))); - } } diff --git a/nondex-test/src/test/java/edu/illinois/nondex/core/ClassTestHelper.java b/nondex-test/src/test/java/edu/illinois/nondex/core/ClassTestHelper.java index b99555cb..d50fc8f2 100644 --- a/nondex-test/src/test/java/edu/illinois/nondex/core/ClassTestHelper.java +++ b/nondex-test/src/test/java/edu/illinois/nondex/core/ClassTestHelper.java @@ -28,10 +28,6 @@ a copy of this software and associated documentation files (the package edu.illinois.nondex.core; -@TestAnnotation1 -@TestAnnotation2 -@TestAnnotation3 -@TestAnnotation4 public class ClassTestHelper { public class InnerOne { @@ -50,10 +46,6 @@ public class InnerFour { } - @TestAnnotation1 - @TestAnnotation2 - @TestAnnotation3 - @TestAnnotation4 public Integer field1; public Integer field2; @@ -86,11 +78,7 @@ public ClassTestHelper(Integer f1, Integer f2, Integer f3, Integer f4) { field4 = f4; } - @TestAnnotation1 - @TestAnnotation2 - @TestAnnotation3 - @TestAnnotation4 - public int m1(@TestAnnotation1 @TestAnnotation2 @TestAnnotation3 @TestAnnotation4 Integer param) + public int m1(Integer param) throws NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException, ClassCastException, Exception { return param; } diff --git a/nondex-test/src/test/java/edu/illinois/nondex/core/FieldTest.java b/nondex-test/src/test/java/edu/illinois/nondex/core/FieldTest.java deleted file mode 100644 index 733ed66f..00000000 --- a/nondex-test/src/test/java/edu/illinois/nondex/core/FieldTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* -The MIT License (MIT) -Copyright (c) 2015 Alex Gyori -Copyright (c) 2015 Owolabi Legunsen -Copyright (c) 2015 Darko Marinov -Copyright (c) 2015 August Shi - - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -package edu.illinois.nondex.core; - -import static org.hamcrest.core.IsEqual.equalTo; -import static org.hamcrest.core.IsNot.not; -import static org.junit.Assert.assertThat; - -import java.lang.reflect.Field; - -import org.junit.Before; -import org.junit.Test; - -public class FieldTest { - private Field myField; - - @Before - public void setUp() throws NoSuchFieldException { - Class clazz = ClassTestHelper.class; - myField = clazz.getField("field1"); - } - - @Test - public void getDeclaredAnnotationsTest() { - assertThat(myField.getDeclaredAnnotations(), not(equalTo(myField.getDeclaredAnnotations()))); - } - - @Test - public void getAnnotationsTest() { - assertThat(myField.getAnnotations(), not(equalTo(myField.getAnnotations()))); - } -} diff --git a/nondex-test/src/test/java/edu/illinois/nondex/core/MethodTest.java b/nondex-test/src/test/java/edu/illinois/nondex/core/MethodTest.java index 36a102a3..8e6444de 100644 --- a/nondex-test/src/test/java/edu/illinois/nondex/core/MethodTest.java +++ b/nondex-test/src/test/java/edu/illinois/nondex/core/MethodTest.java @@ -46,11 +46,6 @@ public void setUp() throws NoSuchMethodException { myMethod = clazz.getMethod("m1", Integer.class); } - @Test - public void getDeclaredAnnotationsTest() { - assertThat(myMethod.getDeclaredAnnotations(), not(equalTo(myMethod.getDeclaredAnnotations()))); - } - @Test public void getExceptionTypesTest() { assertThat(myMethod.getExceptionTypes(), not(equalTo(myMethod.getExceptionTypes()))); @@ -60,9 +55,4 @@ public void getExceptionTypesTest() { public void getGenericExceptionTypesTest() { assertThat(myMethod.getGenericExceptionTypes(), not(equalTo(myMethod.getGenericExceptionTypes()))); } - - @Test - public void getParamaterAnnotationsTest() { - assertThat(myMethod.getParameterAnnotations(), not(equalTo(myMethod.getParameterAnnotations()))); - } } diff --git a/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation1.java b/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation1.java deleted file mode 100644 index 50d1fba2..00000000 --- a/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation1.java +++ /dev/null @@ -1,35 +0,0 @@ -/* -The MIT License (MIT) -Copyright (c) 2015 Alex Gyori -Copyright (c) 2015 Owolabi Legunsen -Copyright (c) 2015 Darko Marinov -Copyright (c) 2015 August Shi - - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -package edu.illinois.nondex.core; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface TestAnnotation1 {} diff --git a/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation2.java b/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation2.java deleted file mode 100644 index 00a758b0..00000000 --- a/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation2.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -The MIT License (MIT) -Copyright (c) 2015 Alex Gyori -Copyright (c) 2015 Owolabi Legunsen -Copyright (c) 2015 Darko Marinov -Copyright (c) 2015 August Shi - - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -package edu.illinois.nondex.core; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface TestAnnotation2 { -} diff --git a/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation3.java b/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation3.java deleted file mode 100644 index 758763a6..00000000 --- a/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation3.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -The MIT License (MIT) -Copyright (c) 2015 Alex Gyori -Copyright (c) 2015 Owolabi Legunsen -Copyright (c) 2015 Darko Marinov -Copyright (c) 2015 August Shi - - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -package edu.illinois.nondex.core; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface TestAnnotation3 { -} diff --git a/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation4.java b/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation4.java deleted file mode 100644 index ec33349a..00000000 --- a/nondex-test/src/test/java/edu/illinois/nondex/core/TestAnnotation4.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -The MIT License (MIT) -Copyright (c) 2015 Alex Gyori -Copyright (c) 2015 Owolabi Legunsen -Copyright (c) 2015 Darko Marinov -Copyright (c) 2015 August Shi - - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -package edu.illinois.nondex.core; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface TestAnnotation4 { -}