How can I programmatically enable assert for particular classes, instead of specifying command line param "-ea"?
public class TestAssert {
private static final int foo[] = new int[]{4,5,67};
public static void main(String []args) {
assert foo.length == 10;
}
}
Try
ClassLoader loader = getClass().getClassLoader();
setDefaultAssertionStatus(true);
or
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
EDIT:
based on the comments
ClassLoader loader = ClassLoader.getSystemClassLoader();
loader.setDefaultAssertionStatus(true);
Class<?> c = loader.loadClass("MyClass");
MyClass myObj = (MyClass) c.newInstance();
public class MyClass {
private static final int foo[] = new int[]{4,5,67};
MyClass()
{
assert foo.length == 10;
}
}
This was a comment to #bala's good answer, but it got too long.
If you just enable assertions then call your main class--your main class will be loaded before assertions are enabled so you will probably need a loader that doesn't reference anything else in your code directly. It can set the assertions on then load the rest of the code via reflection.
If assertions aren't enabled when the class is loaded then they should be "Compiled Out" immediately so you are not going to be able to toggle them on and off. If you want to toggle them then you don't want assertions at all.
Due to runtime compiling, something like this:
public myAssertNotNull(Object o) {
if(checkArguments)
if(o == null)
throw new IllegalArgumentException("Assertion Failed");
}
Should work nearly as fast as assertions because if the code is executed a lot and checkArguments is false and doesn't change then the entire method call could be compiled out at runtime which will have the same basic effect as an assertion (This performance depends on the VM).
You can enable/disable assertions programmatically too:
http://download.oracle.com/docs/cd/E19683-01/806-7930/assert-5/index.html
It is possible to enable or disable assertions using reflection. As usual with reflection, the solution is fragile and may not be appropriate for all usage scenarios. However, if applicable and acceptable, it is more flexible than setClassAssertionStatus because it allows to enable/disable assertions checks at various points in the execution, even after the class is initialized.
This technique requires a compiler that generates a synthetic static field to indicate whether assertions are enabled or not. For example, both javac and the Eclipse compiler generate field $assertionsDisabled for any class that contains an assert statement.
This can be verified as follows:
public class A {
public static void main(String[] args) {
assert false;
System.out.println(Arrays.toString(A.class.getDeclaredFields()));
}
}
Setting the desired assertion status just comes down to setting this field (note the inverted boolean value):
// Helper method in any class
public static void setAssertionsEnabled(Class<?> clazz, boolean value)
throws ReflectiveOperationException
{
Field field = clazz.getDeclaredField("$assertionsDisabled");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(Test.class, !value);
}
The simplest & best way can be:
public static void assertion(boolean condition, String conditionFailureMessage)
{
if(!condition)
throw new AssertionError(conditionFailureMessage);
}
No need to set -ea as VM argument .
call the function like :
assertion(sum>=n,"sum cannot be less than n");
If assertion fails, code will give AssertionError, else code will run safely.
Related
I have created a custom Predicate below and want to test it using mockito. I am creating the mocks of the specific exception classes since these dont have public constructor. After running the test assert is failing since the predicate is returning false instead of true. On printing the class of the mocked exception it has WebClientResponseException$ServiceUnavailable$MockitoMock$54675.Seems like the mock is not recognized correctly. Am I doing something wrong here?
PredicateTest
#ExtendsWith(MockitoExtention.class)
class PredicateTest{
#InjectMocks
CustomPredicate customPredicate;
#Test
public void testPredicate(){
final ServiceUnavailable serviceUnavailable = mock(ServiceUnAvailable.class);
assertTrue(customPredicate.test(serviceUnavailable))
}
}
CustomPredicate
CustomPredicate implements Predicate<Throwable>{
private static final List<Class<?>> Exceptions= Arrays.asList(WebClientResponseException.ServiceUnavailable.class);
private static final Predicate<? super Throwable> ClassToControl= throwable -> Exception.contain(throwable.getClass());
#Override
public boolean test(Throwable t){
return ExceptionUtils.getThrowableList(t).stream().anyMatch(ClassToControl);
}
}
Actually the problem is in mock(ServiceUnAvailable.class) - when you create an object this way it will have a class ServiceUnAvailable$MockitoMock, not a ServiceUnAvailable.class, it means that the next your check fill fail:
Predicate<? super Throwable> ClassToControl= throwable -> Exception.contain(throwable.getClass());
Because Exceptions list doesn’t contain element ServiceUnAvailable$MockitoMock.
In order to test exceptions this way I would suggest the next fix (I changed the code a little bit, but I hope the idea is clear):
Predicate:
public class CustomPredicate implements Predicate<Throwable> {
private final List<Class<?>> exceptions;
private final Predicate<? super Throwable> classToControl;
public CustomPredicate(Class<?>... exceptions) {
this(Arrays.asList(exceptions));
}
public CustomPredicate(List<Class<?>> exceptions) {
this.exceptions = exceptions;
this.classToControl = throwable -> this.exceptions.contains(throwable.getClass());
}
#Override
public boolean test(final Throwable throwable) {
return ExceptionUtils.getThrowableList(throwable).stream()
.anyMatch(classToControl);
}
}
Test:
public class PredicateTest {
#Test
public void testPredicate() {
final IllegalStateException serviceUnavailable = Mockito.mock(IllegalStateException.class);
CustomPredicate customPredicate = new CustomPredicate(serviceUnavailable.getClass());
assertTrue(customPredicate.test(serviceUnavailable));
}
}
#VolodyaLombrozo correctly identified the root cause of the problem:
var serviceUnavailableMock = mock(ServiceUnavailable.class);
System.out.println(serviceUnavailableMock.getClass());
System.out.println(serviceUnavailableMock.getClass() == ServiceUnavailable.class);
System.out.println(serviceUnavailableMock instanceof ServiceUnavailable);
// class org.example.ServiceUnavailable$MockitoMock$X21NGyAU
// false
// true
On top of his answer, I'd like to suggest more options to change your code:
Let's refactor CustomPredicate:
test() converts wraps input into 1-element list, converts it to a stream, and runs a test with anyMatch. This is confusing and unnecessary.
public class CustomPredicate implements Predicate<Throwable> {
private static final List<Class<?>> Exceptions = List.of(ServiceUnavailable.class);
#Override
public boolean test(Throwable t) {
return Exceptions.contains(t.getClass());
}
}
Fix the test
You have 2 options, depending if you want your predicate to pass on subclasses:
pass actual instance of ServiceUnavailable to test() (use new instead of mocking)
use instanceof check in test (using stream and anyMatch, but on Exceptions list)
All of this assumes that this is dummy code and your Exceptions list is longer.
If you want to test your throwable against one class, a lambda would feel pretty adequate:
Predicate<Throwable> pThrowable1 = t -> t instanceof ServiceUnavailable; // if you care about subclasses
Predicate<Throwable> pThrowable2 = t -> ServiceUnavailable.class.equals(t.getClass()); // if you want strict equality
Update: mockito-inline
If you use mockito-inline, it changes the way the mocks are constructed:
This alternative mock maker which uses a combination of both Java instrumentation API and sub-classing rather than creating a new class to represent a mock.
InlineByteBuddyMockMaker javadoc says:
This mock maker will make a best effort to avoid subclass creation when creating a mock. Otherwise it will use the org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker to create the mock class. That means that the following condition is true
class Foo { }
assert mock(Foo.class).getClass() == Foo.class;
unless any of the following conditions is met, in such case the mock maker fall backs to the the creation of a subclass.
the type to mock is an abstract class.
the mock is set to require additional interfaces.
the mock is explicitly set to support serialization
Thus, if you use mockito-inline the test passes, as there is no subclass created:
var serviceUnavailableMock = mock(ServiceUnavailable.class);
System.out.println(serviceUnavailableMock.getClass());
System.out.println(serviceUnavailableMock.getClass() == ServiceUnavailable.class);
System.out.println(serviceUnavailableMock instanceof ServiceUnavailable);
// class org.example.ServiceUnavailable
// true
// true
So the issue was I was not having mockito-inline jar in the pom. Not sure why but this solved the issue
Driven by curiosity, I tried to export the bytecode of GeneratedMethodAccessor1 (generated by the JVM when using reflection).
I try to get the bytecode of the class the following way:
public class MethodExtractor {
public static void main(String[] args) throws Exception {
ExampleClass example = new ExampleClass();
Method exampleMethod = ExampleClass.class
.getDeclaredMethod("exampleMethod");
exampleMethod.setAccessible(true);
int rndSum = 0;
for (int i = 0; i < 20; i++) {
rndSum += (Integer) exampleMethod.invoke(example);
}
Field field = Method.class.getDeclaredField("methodAccessor");
field.setAccessible(true);
Object methodAccessor = field.get(exampleMethod);
Field delegate = methodAccessor.getClass().getDeclaredField("delegate");
delegate.setAccessible(true);
Object gma = delegate.get(methodAccessor);
ByteBuddyAgent.installOnOpenJDK();
try {
ClassFileLocator classFileLocator = ClassFileLocator.AgentBased
.fromInstalledAgent(gma.getClass().getClassLoader());
Unloaded<? extends Object> unloaded = new ByteBuddy().redefine(
gma.getClass(), classFileLocator).make();
Map<TypeDescription, File> saved = unloaded.saveIn(Files
.createTempDirectory("javaproxy").toFile());
saved.forEach((t, u) -> System.out.println(u.getAbsolutePath()));
} catch (IOException e) {
throw new RuntimeException("Failed to save class to file");
}
}
}
I however get the following error when executing this class:
Exception in thread "main" java.lang.NullPointerException
at net.bytebuddy.dynamic.scaffold.TypeWriter$Engine$ForRedefinition.create(TypeWriter.java:172)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1182)
at net.bytebuddy.dynamic.scaffold.inline.InlineDynamicTypeBuilder.make(InlineDynamicTypeBuilder.java:244)
at reegnz.dyna.proxy.extractor.MethodExtractor.main(MethodExtractor.java:48)
Basically I first iterate on the method call enough times for the JVM to inflate the method (generate the GeneratedMethodAccessor) and then try to redefine the class to get the bytecode.
I tried the same method to export a generated Proxy class, and it worked flawlessly. That's what drove me to try this.
It seems that the DelegatingClassLoader of the GeneratedMethodAccessor1 class can't even reload the class when I try to load the class with the loadClass method.
Any ideas how I could retrieve the bytecode for GeneratedMethodAccessor classes?
First of all, the NullPointerException is a bug, I just fixed that. The loader should have thrown an IllegalArgumentException instead but it never got that far. Thanks for bringing this to my attention.
Boiled down, the problem Byte Buddy is facing is that
gma.getClass().getClassLoader().findClass(gma.getClass().getName());
throws a ClassNotFoundException. This is a consequence of using a DelegatingClassLoader for the accessor classes. As an educated guess, I think that this class loader intends to shield its classes from the outside in order to make them easily garbage collectable. However, not allowing the lookup of a class what somewhat breaks the contract for a ClassLoader. Apart from that, I assume that this loading routine will be refactored to use the JDK's anonymous class loaders at some point in the future (similar to classes representing lambda expressions). Strangely enough, it seems like the source code for the DelegatingClassLoader is not available in the JDK even though I can find it in the distribution. Probably, the VM treats these loader specially at some place.
For now, you can use the following ClassFileTransformer which uses some reflection magic on the class loader to locate the loaded class and to then extract the byte array. (The ClassFileLocator interface only takes a name instead of a loaded class in order to allow working with unloaded types which is normally always the case. No idea why this does not work in this case.)
class DelegateExtractor extends ClassFileLocator.AgentBased {
private final ClassLoader classLoader;
private final Instrumentation instrumentation;
public DelegateExtractor(ClassLoader classLoader, Instrumentation instrumentation) {
super(classLoader, instrumentation);
this.classLoader = classLoader;
this.instrumentation = instrumentation;
}
#Override
public Resolution locate(String typeName) {
try {
ExtractionClassFileTransformer classFileTransformer =
new ExtractionClassFileTransformer(classLoader, typeName);
try {
instrumentation.addTransformer(classFileTransformer, true);
// Start nasty hack
Field field = ClassLoader.class.getDeclaredField("classes");
field.setAccessible(true);
instrumentation.retransformClasses(
(Class<?>) ((Vector<?>) field.get(classLoader)).get(0));
// End nasty hack
byte[] binaryRepresentation = classFileTransformer.getBinaryRepresentation();
return binaryRepresentation == null
? Resolution.Illegal.INSTANCE
: new Resolution.Explicit(binaryRepresentation);
} finally {
instrumentation.removeTransformer(classFileTransformer);
}
} catch (Exception ignored) {
return Resolution.Illegal.INSTANCE;
}
}
}
To further simplify your code, you can use the ClassFileLocators directly instead of applying a rewrite which as a matter of fact might slightly modify the class file even if you do not apply any changes to a class.
I'm trying to write an expression or series of statements of Java source code that when written inside a static method evaluates to null, but if the method is non-static evaluates to this.
My initial idea was to 'overload' on static vs non-static, as below:
public class test {
public void method1() {
System.out.println(getThisOrNull());
}
public static void method2() {
System.out.println(getThisOrNull());
}
private static Object getThisOrNull() {
return null;
}
private Object getThisOrNull() {
return this;
}
public static void main(String[] args) {
test t = new test();
System.out.println(t);
t.method1();
t.method2();
}
}
Unfortunately this isn't actually legal Java, you can't 'overload' like that and it just gives a compiler error:
test.java:14: error: method getThisOrNull() is already defined in class test
private Object getThisOrNull() {
^
1 error
Clearly in an ideal world I wouldn't write it like that to begin with, but the problem is this code will be generated automatically by a tool that is not really semantically or syntactically enough to distinguish between the static vs non-static case.
So, how can I write some source code that, although byte for byte identical compiles and behaves differently in depending on the presence of the static modifier for the method?
This can be achieved with a trick and a bit of help from Java's reflection facilities. It's ugly, but it works:
import java.lang.reflect.Field;
public class test {
public void method1() {
System.out.println(getThisOrNull(new Object(){}));
}
public static void method2() {
System.out.println(getThisOrNull(new Object(){}));
}
private static Object getThisOrNull(final Object o) {
for (Field f: o.getClass().getDeclaredFields()) {
if (f.getType().equals(test.class)) {
try {
return f.get(o);
}
catch (IllegalAccessException e) {
// Omm nom nom...
}
}
}
return null;
}
public static void main(String[] args) {
test t = new test();
System.out.println(t);
t.method1();
t.method2();
}
}
This compiles and runs as hoped for:
test#183f74d
test#183f74d
null
The trick that makes this possible is the use of new Object(){}, which creates a new, anonymous class within the existing method that we're trying to figure out if it's static or not. The behaviour of this is subtly different between the two cases.
If the goal were just to figure out if the method is static or not we could write:
java.lang.reflect.Modifiers.isStatic(new Object(){}.getClass().getEnclosingMethod().getModifiers())
Since we want to get this (when available) we need to do something slightly different. Fortunately for us classes defined within the context of an instance of an object in Java get an implicit reference to the class that contains them. (Normally you'd access it with test.this syntax). We needed a way to access test.this if it existed, except we can't actually write test.this anywhere because it too would be syntactically invalid in the static case. It does however exist within the object, as a private member variable. This means that we can find it with reflection, which is what the getThisOrNull static method does with the local anonymous type.
The downside is that we create an anonymous class in every method we use this trick and it probably adds overheads, but if you're backed into a corner and looking for a way of doing this it does at least work.
When I debug through Java code, I often see lot of properties of object that are useful to me in my application to get them and do something with them but I look at the API or javadocs, the class does not have any such properties or getter methods to get these property values. For example:
myPhoneCallObj.foo has value "bar" in debugger
myPhoneCallObj.baz has value otherObj which in turn has other values like otherObj.baz
I cannot do in Java:
String myValue = myPhoneCallObj.foo
as it would not compile in Java but in Groovy I can write above code and during runtime, it gets the value I need. How the same can be done in Java code?
myPhoneCallObj is an instance of Java Interface PhoneCall and the debugger was showing this as of type PhoneCallImpl ( third party implementation of the interface). I do not have access to source code of that third party to look into to understand but the Interface has complete documentation and Javadoc for the APIs.
Given a class like:
class X
{
private int value;
#Override
public String toString()
{
return (Integer.toString(value));
}
}
You can do this:
import java.lang.reflect.Field;
public class Test
{
public static void main(final String[] argv)
throws NoSuchFieldException,
IllegalArgumentException,
IllegalAccessException
{
final X x;
x = new X();
System.out.println(x);
changeValue(x);
System.out.println(x);
}
private static void changeValue(final X x)
throws NoSuchFieldException,
IllegalArgumentException,
IllegalAccessException
{
final Class<X> clazz;
final Field field;
clazz = X.class;
field = clazz.getDeclaredField("value");
field.setAccessible(true);
field.set(x, Integer.MAX_VALUE);
}
}
The key here is the call to field.setAccessible(true); which says that even though value is private allow it to be accessed.
However there is typically a reason why a field is private, and you should not be surprised if your code breaks with a later release of the 3rd party code that you are manipulating.
Are these properties private or protected in scope? The only properties that you will be able to directly access are public properties, but all variables will show up in a debug object inspector.
If you absolutely need to get the value, you can use reflection. (Which is likely what Groovy is doing)
Is there a method/function in Java that checks if another method/function is available just like function_exists(functionName) in PHP?
Here I am referring to a method/function of static class.
You can find out if a method exists in Java using reflection.
Get the Class object of the class you're interested in and call getMethod() with the method name and parameter types on it.
If the method doesn't exist, it will throw a NoSuchMethodException.
Also, please note that "functions" are called methods in Java.
Last but not least: keep in mind that if you think you need this, then chances are that you've got a design problem at hand. Reflection (which is what the methods to inspect the actual Java classes is called) is a rather specialized feature of Java and should not generally be used in business code (although it's used quite heavily and to some nice effects in some common libraries).
I suspect you're looking for Class.getDeclaredMethods and Class.getMethods which will give you the methods of a class. You can then test whether the one you're looking for exists or not, and what it's parameters are etc.
You can use Reflections to lookup if the method exists:
public class Test {
public static void main(String[] args) throws NoSuchMethodException {
Class clazz = Test.class;
for (Method method : clazz.getDeclaredMethods()) {
if (method.getName().equals("fooBar")) {
System.out.println("Method fooBar exists.");
}
}
if (clazz.getDeclaredMethod("fooBar", null) != null) {
System.out.println("Method fooBar exists.");
}
}
private static void fooBar() {
}
}
But Reflection is not really fast so be careful when to use it (probably cache it).
Try using the Class.getMethod() method of the Class class =)
public class Foo {
public static String foo(Integer x) {
// ...
}
public static void main(String args[]) throws Exception {
Method fooMethod = Foo.class.getMethod("foo", Integer.class);
System.out.println(fooMethod);
}
}
Here my solution using reflection...
public static boolean methodExists(Class clazz, String methodName) {
boolean result = false;
for (Method method : clazz.getDeclaredMethods()) {
if (method.getName().equals(methodName)) {
result = true;
break;
}
}
return result;
}
You can use the reflection API to achieve this.
YourStaticClass.getClass().getMethods();
You can do this like this
Obj.getClass().getDeclaredMethod(MethodName, parameterTypes)