I thought this would be a trivial matter, but I can't seem to find a method similar to class_exists in Java. I'm writing a test to verify that a class name is defined. How can I replicate this in Java with jUnit?
<?php
$this->assertTrue(class_exists('Car'), 'Should have a class called "Car"');
TestCar.java
import org.junit.Assert;
import org.junit.Test;
public class TestCar {
#Test
public void testCarExists() {
try {
Class.forName("Car");
} catch(ClassNotFoundException e) {
Assert.fail("Should create a class called 'Car'.");
}
}
}
Car.java
public class Car {
// just enough :-)
}
One advantage of Java is that you have a compiler, so usually this is a non-issue. If you compile your code properly and then, for some reason, drop a required jar file from the runtime environment, you'll get a java.lang.ClassNotFoundException, so that should be enough.
If you want to be super-extra-safe, you could try calling Class.forName:
#Test
public void testClassExists {
try {
Class.forName("org.mypackage.Car");
} catch (ClassNotFoundException e) {
Assert.fail("should have a class called Car");
}
}
Related
The following example runs MyClass#myMethod() only if it is public. It does not run it if it is private.
How to run even if private?
import org.apache.commons.lang3.reflect.MethodUtils;
import javax.annotation.PostConstruct;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Created by dims on 13.10.2016.
*/
public class CallPrivateMethodTest {
#Retention(RUNTIME)
#Target(METHOD)
public #interface MyAnnotation {
}
public static class MyClass {
#MyAnnotation
private void myMethod() {
System.out.println("myMethod() ran");
}
}
public static void main(String[] args) {
MyClass myObject = new MyClass();
List<Method> methods = MethodUtils.getMethodsListWithAnnotation(myObject.getClass(), MyAnnotation.class);
for(int i=0; i<methods.size(); ++i) {
try {
methods.get(i).invoke(myObject);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
You have to call setAccessible(true) on your method.
See the Javadoc of AccessibleObject, which in turn is a supertype of Method.
In your example:
methods.get(i).setAccessible(true);
methods.get(i).invoke(myObject);
EDIT: As GhostCat pointed out in his answer, not all reflection calls return private methods, too. It seems that MethodUtils#getMethodsListWithAnnotation in fact does not return them.
To solve this problem, you'd have to fetch those methods by yourself:
MyClass myObject = new MyClass ();
Method[] allMethods = myObject.getClass ().getDeclaredMethods ();
List<Method> annotatedMethods = Arrays.stream (allMethods)
.filter (m -> m.getAnnotation (MyAnnotation.class) != null)
.collect (Collectors.toList ());
for (Method method: annotatedMethods) {
try {
method.setAccessible (true);
method.invoke (myObject);
} catch (IllegalAccessException e) {
e.printStackTrace ();
} catch (InvocationTargetException e) {
e.printStackTrace ();
}
}
Basically, you need to run a private method from the class itself. Maybe you should rethink your code ? Otherwise, Alex's answer will do the trick.
More informations on access levels : https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
And if you want to use Reflection, you can find even more infos about the behavior here : Java reflection - impact of setAccessible(true)
Actually, there can be two reasons why your code doesn't work:
That private method shows up in that list; but before calling it, you have to make it accessible (you already got an answer for that)
Depending on the implementation of that Util class you are using, maybe getMethodsListWithAnnotation returns a list that simply doesn't include any private methods? ( you see, the mechanism in java reflection to get a hold on private methods is different than for public methods. thus it wouldnt surprise me if that util class is making the same distinction).
And in any case: private methods are private for a reason. They represent internal implementation details. They are subject to be changed all the time.
In that sense: your real problem is that you think there is a valid reason to invoke a private method using reflection. You should work on that first. If you really think that method should be annotated; and be called via reflection; then at least make it public.
I want to check String is interface or not using Reflection method .isInterface. Here is what I tried but it gives Class not found exception.
public class CheckingClassType {
public static void main(String args[]) {
try {
Class c = Class.forName("String");
System.out.println(c.isInterface());
} catch (Exception e) {
System.out.println(e);
}
}
}
Use Class c = Class.forName("java.lang.String");
You need to give the full package name of the class. The reflection needs to know that to instantiate the class name as multiple classes with same name can exist in different packages.
I have been working on a code that does 2 things:
Has a class that performs computations (logic)
has a class that displays the result.
I am wondering if it is possible to use try/catch statements in the Display class, where I would attempt to catch exceptions originating in the logic class.
Where Display would execute a line similar to logic.execute(input);
I was able to create a custom exception class where the following is placed in display class:
try{
logic.execute(input);
}catch(CustomException e){
//print statements
}
However I would like to be able to print exactly the error that occured, such as NullPointerException.
When i say print, i mean output in console. (but it must originate from display class)
If such a monstrosity is possible, please let me know.
Thank You guys!
Yes, it's possible.
You will need your custom exception class to extend RuntimeException instead of Exception, or the compiler will complain that you are not catching the exception that you throw.
See this post: Throwing custom exceptions in Java
Simple working example:
public class ExceptionTest
{
public static void main(String[] args)
{
SomeClass myObject = new SomeClass();
myObject.testFunction();
}
}
public class SomeClass
{
private SomeOtherClass someOther = new SomeOtherClass();
public void testFunction()
{
try{
someOther.someOtherFunction();
}
catch(Exception e){
System.out.println(e.toString());
}
}
}
public class SomeOtherClass
{
public void someOtherFunction()
{
throw new CustomException("This is a custom exception!");
}
}
public class CustomException extends RuntimeException
{
public CustomException(String message)
{
super(message);
}
}
Hi I am using the following code from this site: http://java.sun.com/developer/technicalArticles/ALT/Reflection/
But when I am running it it showing exception java.lang.ClassNotFoundException: A
May be I am going somewhere wrong Please help.
Here is the code:
package com.Test;
class A {}
public class instance1 {
public static void main(String args[])
{
try {
Class cls = Class.forName("A");
System.out.println("gfsdga");
boolean b1
= cls.isInstance(new Integer(37));
System.out.println(b1);
boolean b2 = cls.isInstance(new A());
System.out.println(b2);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
The class is actually called com.Test.A because you've declared it within the com.Test package - Class.forName() takes the package-qualified class name. (Note that com.Test is a pretty odd package name, too.)
You need Class.forName("com.Test.A") instead.
All of my tests for my Groovy code look like this
public void testButtons() {
try {
page.getButtons();
} catch (Exception e) {
throw org.codehaus.groovy.runtime.StackTraceUtils.sanitize(e);
}
}
because I need to sanitize any possible StackTrace that appears (otherwise it's very hard to read since it's got all the Groovy meta-code). Is there any way to specify that all JUnit tests get wrapped in particular way (like an error handler)?
Note: I am running these in Eclipse, but if there's a way to do this in IntelliJ or Netbeans, that would be good to know.
Yes, use a Rule. Basically you have to have a class which implements the MethodRule interface that handles the exception handling in the apply method by substituting its own Statement implementation that has the try/catch in it.
To use a rule you define a field in the test class like so:
#Rule public MethodRule exceptionCleanser = new ExceptionCleanser();
A first cut implementation would probably look something like this:
public class ExceptionCleanser implements MethodRule {
public Statement apply(final Statement base, FrameworkMethod method, Object target) {
return new Statement() {
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (Exception e) {
throw org.codehaus.groovy.runtime.StackTraceUtils.sanitize(e);
}
}
};
}
}
The above is totally untested, but you should be able to get the idea. The #Rule annotation was introduced in JUnit 4.7, so you may need to update to use it.