First exception handling - java

I am trying to do a very basic code but got an error from jvm. Someone can help me ? I really can't find any solution :( The error states : cannot find any symbol when is trying to create the bello object.
import java.util.*;
import java.io.*;
public class Test {
public static void main (String[] args) {
try {
bello ola = new bello();
ola.ciao(3);
} catch( BadException se) {
} finally {
} // end of try
class bello {
void ciao (int i) throws BadException {
if (i == 5 ) {
throw new BadException();
} // end of if
}
}
class BadException extends Exception {
public BadException() {
}
}
}
}

Classes declared in methods may only be used after their declaration in the source code. Please note, however, that declaring classes in methods is strongly discouraged. Also, as noted by JB Nizet, please indent your code/respect naming conventions if you want to be able to debug anything, ever.

Did you write everything in this one file?
And you wrote the class-definitions into the main-function?
In Java you have do split up your classes in a separate file.
By the way the convention for classnames is Uppercase in the first letter.
Test.java
public class Test{
public static void main (String[] args) {
...
}
}
Bello.java
class Bello {
...
}
BadException.java
class BadException extends Exception {
public BadException() {
...
}
}

Related

Soot: How to analyze a java file in a package?

I have two java files under the tests directory.
I use the following code to set up Soot for further analysis(i.e., construct a call graph) but meet an error of are the packages set properly?.
Main.java:
public class Main {
static void setupSoot() {
Options.v().set_prepend_classpath(true);
Options.v().set_process_dir(Collections.singletonList("./tests"));
Options.v().set_whole_program(true);
Scene.v().loadNecessaryClasses();
}
// Following function also doesn't work and has a similar error message
//static void setupSoot() {
// Options.v().set_prepend_classpath(true);
// Options.v().set_process_dir(Collections.singletonList("./tests"));
// Scene.v().loadClassAndSupport("FooBar");
//}
public static void main(String[] args) {
setupSoot();
// ....
}
}
And I get the following error message:
Exception in thread "main" java.lang.RuntimeException: Error: couldn't find class: FooBar are the packages set properly?
at soot.JastAddInitialResolver.resolveFromJavaFile(JastAddInitialResolver.java:119)
at soot.JavaClassSource.resolve(JavaClassSource.java:69)
at soot.SootResolver.bringToHierarchyUnchecked(SootResolver.java:253)
at soot.SootResolver.bringToHierarchy(SootResolver.java:221)
at soot.SootResolver.bringToSignatures(SootResolver.java:292)
at soot.SootResolver.bringToBodies(SootResolver.java:332)
at soot.SootResolver.processResolveWorklist(SootResolver.java:171)
at soot.SootResolver.resolveClass(SootResolver.java:141)
at soot.Scene.loadClass(Scene.java:1009)
at soot.Scene.loadClassAndSupport(Scene.java:994)
at soot.Scene.loadNecessaryClasses(Scene.java:1822)
at Main.setupSoot(Main.java:18)
at Main.main(Main.java:21)
If I complie two test files into .class files then I will get following error message:
Exception in thread "main" soot.SootResolver$SootClassNotFoundException: couldn't find class: tests.FooBar (is your soot-class-path set properly?)
at soot.SootResolver.bringToHierarchyUnchecked(SootResolver.java:245)
at soot.SootResolver.bringToHierarchy(SootResolver.java:221)
at soot.SootResolver.bringToSignatures(SootResolver.java:292)
at soot.SootResolver.bringToBodies(SootResolver.java:332)
at soot.SootResolver.processResolveWorklist(SootResolver.java:171)
at soot.SootResolver.resolveClass(SootResolver.java:141)
at soot.Scene.loadClass(Scene.java:1009)
at soot.Scene.loadClassAndSupport(Scene.java:994)
at soot.Scene.loadNecessaryClasses(Scene.java:1822)
at Main.setupSoot(Main.java:18)
at Main.main(Main.java:21)
I beleive that soot prepend_classpath is true since it works well when two test files are not in the package (i.e., remove package tests from both files).
Two files in tests directory are as follows:
Pack.java:
package tests;
public class Pack {
public static void main(String[] args) {
int s = 10;
}
}
FooBar.java
package tests;
public class FooBar {
public static void main(String[] args) {
FooBar callFooBar = new FooBar();
callFooBar.foo(10);
}
void foo(int a) {
bar(a);
}
void bar(int a) {
for (int i = 0; i < a; i++) {
i += a;
}
}
}
I solved this problem. The issue is that the path of the test files is wrong.
Now my project structure is as follows:
-ProjectRoot
|--src
|--Main.java
|--testers
|--easycase
|--FooBar.java
|--Pack.java
and My Main.java:
public class Main {
static void setupSoot() {
Options.v().set_prepend_classpath(true);
// Options.v().set_soot_classpath("xxxxx:xxxxx/xxxxx.jar") // For external packages
Options.v().set_process_dir(Collections.singletonList("./testers"));
Options.v().set_whole_program(true);
Scene.v().loadNecessaryClasses();
}
public static void main(String[] args) {
setupSoot();
Scene.v().loadAndSupport("esaycase.FooBar");
// Do something here
}
}
Note that the first line is package easycase; for both test files.

Handling a custom exception without changing the test class (java)

I need to throw a couple times a custom exception. A test class is checking if my solution works but I'm not allowed to make any changes to this class which leads me to my problem.
I simplified the problem here, because the whole code is not needed here
public class Test{
public static final String s = "0test";
#Test
public void testZero(){
Solver sol = new Solver(Parser.run(s));
//IntelliJ is underlining "run" because "Unhandled exception: ParseException", a
//simple solution could be adding "throws ParseException" in the head, but I'm not
//allowed to change the test class
}
}
public class Parser{
public static Pars run(String input) throws ParseException{
if(input.charAt(0) == '0'){
throw new ParseException("...");
}
}
}
public class ParseException extends Exception{
public ParseException(String mess){
super(mess);
}
}
I'm not allowed to make any changes to this class which leads me to my problem.
There is no way that you can throw an Exception to the Test class without catching it over there.
BUT you can prematurely just catch it inside the Parser#run(String input).
Instead of this:
public static Pars run(String input) throws ParseException{
if(input.charAt(0) == '0'){
throw new ParseException("...");
}
}
You could (as I said) catch it in the method instead.
public static Pars run(String input) {
try {
if(input.charAt(0) == '0'){
throw new ParseException("...");
}
} catch (ParseException e) {
// System.out.println(e.toString());
// Just handle it over here if you can't edit Test.java ...
}
}
I have found the solution for my problem.
In my ParseException class, I need to change it to:
public class ParseException extends IllegalArgumentException{...}
Further into the task, the test class didnt accept my exception because there was a IllegalArgumentException exspected.
Changing it into "extends IllegalArgumentException" solves the problem, so I dont need "throws ParseException" in the headings and no try,catch statements

how to test my custom exception with unit test

Hello I have wrote a test cases for my logic and all these are working nicely. however, I have no idea how to test my custom exceptions. My code below;
#Component
public class PlaneFactory {
public Plane getPlane(String planeType) {
if (StringUtils.isBlank(planeType)) {
throw new PlaneTypeNotFoundException();
}
if (planeType.equalsIgnoreCase("lightJet")) {
return new LightJet();
} else if (planeType.equalsIgnoreCase("midJet")) {
return new MidJet();
}
else {
throw new InvalidPlaneTypeException();
}
my custom exceptions below;
PlaneTypeNotFoundException class below;
public class PlaneTypeNotFoundException extends RuntimeException {
private static final long serialVersionUID = 4314211343358454345L;
public PlaneTypeNotFoundException() {
super("You have not enter anything to check a plane");
}
}
InvalidPlaneTypeException below;
public class InvalidPlaneTypeException extends RuntimeException {
public InvalidPlaneTypeException() {
super("You need to enter one of following plane types : {LightJet, MidJet}");
}
}
which methods are suitable to use ? I mean in this scenario should I use assertThrows or just use expected annotations ?
for PlaneTypeNotFoundException I have tried something below which it did not work
#Test
public void testPlaneFactory_isEmptyOrNull_ThenReturnException() {
String planeType = "";
LightJet lightJet= (LightJet) planeFactory.getPlane(planeType);
assertThrows(PlaneNotFoundException.class, () -> lightJet.getType().equalsIgnoreCase(planeType), "You have not enter anything to check a plane");
}
If I follow your code correctly then the executable lambda in assertThrows() should be the code that you expect to generate the exception:
public void testPlaneFactory_isEmptyOrNull_ThenReturnException() {
assertThrows(PlaneNotFoundException.class, () -> planeFactory.getPlane(""));
}
If it does throw an exception then the test should pass.
A test for the second case would be:
void testInvalidPlaneType() {
assertThrows(InvalidPlaneTypeException.class, () -> planeFactory.getPlane("doh"));
}

Java Reflection: Find method usage in custom AbstractProcessor

I'm newbie in reflection. Is there any way to detect where is an specific method invoked? For example:
public class MyClass {
public static void method(){
//DO SOMETHING
}
}
public class Test {
public test(){
MyClass.method();
}
}
public class MyProcessor extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Method method = MyClass.class.getDeclaredMethod("method");
Class classWhereMethodIsInvoked = obtainClassWhereMethodIsInvoked(method);
}
public Class obtainClassWhereMethodIsInvoked(Method method) {
//here I want to search one class that invoke that method, in this case Test.class
}
}
is something like this possible or I am going crazy?
As mentioned in the comments, Apache BCEL is suitable for your problem. Such libraries are often particularly used for determining compile-time information such as method usage and control flow analysis from the generated bytecode, and such information are difficult, if not impossible, to retrieve using reflection. If you use the BCEL solution, you probably no longer require a custom annotation processor.
But since you already seem to be using a custom annotation processor, the whole point of it is to be able to process annotations in the source files. So one way is to define a custom annotation that marks a method being called, and have the custom processor read these annotations to know which classes call which methods:
#CallerClass("MyClass.method")
public class Test {
public test() {
MyClass.method();
}
}
In the above (trivial) example, a custom CallerClass annotation marks that a class calls the method specified in the annotation's element inside parentheses. The annotation processor can read this annotation and construct the caller information.
Yes it doable if you really want it. You can use the classLoader to search through the class path and scan for the method name through all the class files. Below is a very simplistic example to show that it is doable. In the example below I find usage of the "println" method being used in this class. Essentially you can just broaden the scope from one file in my example to all the class files.
public class SearchClasses {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException {
// InputStream is = SearchClasses.class.getClassLoader().getResourceAsStream("resources.SearchClasses.class");
InputStream is = new FileInputStream(new File("build/classes/resources/SearchClasses.class"));
boolean found = false;
Scanner scanner = new Scanner(is);
while (scanner.hasNext()) {
if (scanner.nextLine().contains("println")) {
System.out.print("println found");
found = true;
break;
}
}
if (!found) {
System.out.print("println NOT found");
}
}
public static void testMethod() {
System.out.println("testing");
}
}
In my IDE I had to use the FileInputStream to access the class file I was searching in.... but if you are searching through jar files then you can use the classLoader instead. You would need mechanism to search through all of the class path... this is not impossible but I left it our for brevity.
EDIT: Here is an attempt to get it working completely.. searches all files in class path for your method.
public class SearchClasses {
/**
* #param args the command line arguments
* #throws java.io.FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException, IOException {
printAllFileWithMethod("println");
}
public static void printAllFileWithMethod(String methodName) throws FileNotFoundException, IOException {
Enumeration<URL> roots = SearchClasses.class.getClassLoader().getResources("");
List<File> allClassFiles = new ArrayList<>();
while (roots.hasMoreElements()) {
File root = new File(roots.nextElement().getPath());
allClassFiles.addAll(getFilesInDirectoryWithSuffix(root, "class"));
}
for (File classFile : allClassFiles) {
InputStream is = new FileInputStream(classFile);
boolean found = false;
Scanner scanner = new Scanner(is);
while (scanner.hasNext()) {
if (scanner.nextLine().contains(methodName)) {
System.out.print(methodName + " found in " + classFile.getName() + "\n");
found = true;
break;
}
}
}
}
public static void testMethod() {
System.out.println("testing");
}
static List<File> getFilesInDirectoryWithSuffix(File dir, String suffix) {
List<File> foundFiles = new ArrayList<>();
if (!dir.isDirectory()) {
return foundFiles;
}
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
foundFiles.addAll(getFilesInDirectoryWithSuffix(file, suffix));
} else {
String name = file.getName();
if (name.endsWith(suffix)) {
foundFiles.add(file);
}
}
}
return foundFiles;
}
}
You could define your own mechanism. Use a Map to store the caller of each method :
public static Map<Method, List<String>> callStack = new HashMap<Method, List<String>>();
public static void registerCaller(Method m)
{
List<String> callers = callStack.get(m);
if (callers == null)
{
callers = new ArrayList<String>();
callStack.put(m, callers);
}
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
callers.add(stackTraceElements[3].getClassName());
}
The target class :
class MyClass
{
public static void method()
{
registerCaller(new Object(){}.getClass().getEnclosingMethod());
// DO SOMETHING
}
}
Some caller classes :
package the.package.of;
class Test
{
public void test()
{
MyClass.method();
}
}
class Foo
{
public void bar()
{
MyClass.method();
}
}
And finally, the test :
new Test().test();
new Foo().bar();
Method method = MyClass.class.getDeclaredMethod("method");
for (String clazz : callStack.get(method))
{
System.out.println(clazz);
}
Prints :
the.package.of.Test
the.package.of.Foo
Well, if you use Eclipse as an IDE, you can find the complete call hierarchy via "Open Call Hierarchy" function. This will find all usages of your method in any open Eclipse projects.
However, if you want to find out during runtime programmatically, then you need to integrate some library, that can statically analyze the bytecode of your classpath for use of your method.
You can obtain stack trace right inside the test method:
public class Test {
public void test() {
System.out.println(getCallerClass());
}
public static String getCallerClass() {
for (StackTraceElement e: Thread.currentThread().getStackTrace()) {
if (!"java.lang.Thread".equals(e.getClassName()) && !e.getClassName().equals(Test.class.getName()))
return e.getClassName();
}
return null;
}
}

Simple App Won't Compile in Eclipse (with plugin)?

my code, being practically identical to the code given in BlackBerry's tutorial, has a syntax error in Eclipse. i'm sure there is some small but i'm just not seeing, but my coworker could not find it as well. any ideas would be greatly appreciated. thanks!
Code:
pushScreen(new ABCScreen());
Error:
Cannot make a static reference to the
non-static method pushScreen(Screen)
from the type UiApplication
here is the complete source:
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
public class AwesomeBBCalculator extends UiApplication {
public AwesomeBBCalculator() {
AwesomeBBCalculator app = new AwesomeBBCalculator();
app.enterEventDispatcher();
}
public static void main(String[] args) {
pushScreen(new ABCScreen()); // ERROR LINE
}
}
final class ABCScreen extends MainScreen {
public ABCScreen() {
super();
// add title
LabelField title = new LabelField("Awesome BlackBerry Calculator",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
setTitle(title);
}
public boolean onClose() {
Dialog.alert("Thanks for using the Awesome BlackBerry Calculator!\nGoodbye.");
System.exit(0);
return true;
}
}
The pushScreen method can only be called within an instance of UiApplication. You are trying to call it from a static main method. That does not work. Do this instead...
public void foo()
{
pushScreen(this);
}
public static void main(String[] args)
{
(new ABCScreen()).foo();
}
public void class1()
{
pushScreen(this);
}
public static void main(String[] args)
{
(new NewScreen()).class1();
}
try making an object for the ABCScreen class and then use it or u may try this also:
UiApplication.getUiApplication().pushScreen(new ABCScreen());

Categories