Ignore exceptions when executing bytecode (java)? - java

I have a large program, that i modified in java. I used the intelliJ idea (community edition) IDE for compiling. When i go to run the program, it starts up the GUI and then proceeds to do everthing i want from it, with very few problems (of which are unrelated to the exceptions). But the code always generates class not found exceptions (even the original unmodified code does this once you extract it from the .jar file. Despite these errors, it executes within the IDE perfectly, while still noting the errors, but they don't appear to have an effect on the program. However, when i execute them from within the virtual machine (with java filename) the exceptions which are usually ignored prevent the ultimate execution of the program. The errors are exactly the same as the ones that the iDE shows, but the IDE ignores them! How could i get a virtual machine to ignore the errors and execute the program (is there an option to pass to java - for example java -ignoreerrors filename).
Is this possible, or will i have to alter the code?

There's no way to ignore ClassNotFoundExceptions unless that class isn't actually needed by the code. Some frameworks do that by trying to load a class to discover whether some feature is available. However, if a CNFE is preventing your app from running, you'll just have to fix it. If you show some stack traces, someone might be able to steer you in the right direction.

If you are having trouble with ClassNotFoundExceptions then you can always localize the problem and catch and log using try { ... } catch (...) { ... }.
If you are instead getting ClassNotFoundErrors then it's not a localizable problem with reflection, but a failure to initialize code that's needed. You should try to prune unneeded dependencies but you really shouldn't use classes that haven't initialized properly.
If you absolutely have to, you can always load your program using a custom ClassLoader that generates bogus empty classes for any name that is not resolvable using the system classloader and use that to load your main class. That will replicate, to some degree, what your IDE is doing, though your IDE probably goes the extra step to make sure that partially well-defined classes have the right interface even if some methods are stubbed out because their bodies don't compile.

You can only ignore compiler warnings. You cannot ignore errors.
The errors that IntelliJ shows are coming from the same compiler.
ClassNotFoundException would indicate that your code failed to dynamically load a class at runtime.
This could mean that a required dependency (jar) is missing from your classpath. Try to consult your code documentation and make sure you've resolved all runtime dependencies. Also make sure that the dependent jars are in the classpath otherwise the runtime won't be able to find them.

Related

How to recover from broken plugin throwing AbstractMethodError

I'm modifying a java program to search through a specific folder and load plug-ins at runtime. The plugin code is working fine. I have created an UncaughtExceptionHandler to catch problems with plugins that weren't coded properly, and for the most part that works. Except for one issue (one so far, anyway):
The plugins need to have a class that implements a specific interface, so that the main program recognises them as plugins. If the developer misses one of the abstract methods, an AbstractMethodError gets thrown. It goes through my ExceptionHandler and I'm able to put up a message to the user indicating that there's a problem with the plugin. After that, though, the program just hangs. What I want is the program to continue going so that I can skip the rest of the plugin stuff, remove it from the plugin list, and let the user run the main program without it. I put a try/catch block directly around the call to the missing method, but the catch doesn't get executed. It just goes to the ExceptionHandler and then... I don't know where it goes.
This is my first attempt at exception handling so I'm sure I'm just missing something obvious. Any help would be greatly appreciated. Thanks so much.
The problem with exceptions that sub-class from the Error class is that most of them are not recoverable (in your case it's AbstractMethodError). As per the Error class java-doc:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
I.e. it's not guaranteed that the app is recoverable after an Error is thrown. Depending on how you load/execute that plugin there might be some workarounds. First of all, you could check the loaded plugin class via reflection (some examples) if there is an implementation of the needed methods before actually trying the exectuion - so you could catch/throw an Exception rather than get the Error and hang later.
If it's not an option, you could investigate further on what is actually hanging after getting that error by analyzing thread dump re
Taking thread dumps in production

Does Checkstyle require compiled classes?

Can anyone confirm that Checkstyle is meant to be run with the compiled versions of classes on the classpath?
We currently run it on the Java files alone but recently we've been encountering some errors around the "RedundantThrows" and "JavadocMethod" checks. The error is "Unable to find class information for X". Searching online we've found that the solution is to add the compiled classes to the classpath before running Checkstyle.
Our problem is that our Checkstyle audit currently runs on a server that only has access to the source and we just want to confirm that Checkstyle will in fact need access to compiled classes. Can't seem to find "definitive proof" on the official site.
Checkstyle is perfectly happy with the source files only. Compiled versions of your classes are not required.
However, it is still better to have compiled classes available, because a few individual checks do make use of compiled .class files. These checks mention the fact that they need binaries in their documentation. One is the JavadocMethod check you mention. This one will still function without binaries, but you may see some irritation in the logs.
The other check I can think of needing compiled classes is RedundantThrows. This one will probably not do much good with only sources. You'd have to give it a try.
In both cases, you can suppress the load errors by setting the suppressLoadErrors property to true. Without binaries, the check will not be able to gather inheritance information. So some features of the check will be limited, but it will otherwise work fine or at least not bother you.

Replacing java class?

I'm working on a sandbox feature for my java antivirus, and I've come into a question: Does the specified package on a class matter for compilation?
Example:
I'm running a program that wants to use Runtime.getRuntime().exec(), when the classloader attempts to load that to run a method, does it check the package qualified in the file, if they exist? I would prefer not to try and change files in the JVM, but to simply load ones from a different package. I can accomplish the loading and such, but my only dilemma, will it crash and burn? Inside the java, it would be registered as say, java.lang.Runtime, but the compiled code will say for example pkg.pkg.Runtime and will it need to extend the old runtime? My guess is that extending the old runtime would just break it. Does anyone know anything about this? I'm working on making a testable example, but I'm still a bit away and wanted to get some answers, as well as this might benefit some people.
Does the specified package on a class matter for compilation?
Yes it does matter. A class called pkg.pkg.Runtime() cannot be loaded as if it was java.lang.Runtime.
Furthermore, if my memory is correct, the JVM has some additional security measures in it to prevent normal applications from injecting classes into core packages such as java.lang.
If you need to change the behaviour of the java.lang.Runtime class (for experimental purposes!) then I think you will need to put your modified version on the boot classpath, ahead of the "rt.jar" file.
However:
This level of tinkering can easily result in JVM instability; i.e. hard JVM crashes that are difficult to diagnose.
If your aim is to produce a "production quality" tool, then you will find that things that involve tinkering with the JVM are not considered acceptable. People are going to be very suspicious of installation instructions that say things like "add this to your installed JVM's bootclasspath".
Distributing a "tinkered with" JVM may fall foul of Oracle's Java licensing agreement.
My advice would be to look for a less intrusive way of doing what you are trying to do. For instance, if you are trying to do virus checking, either do it outside of the JVM, or in a custom application classloader.
You commented:
I have a custom classloader, my question is: If I compile a class that is labelled as say, pkg.pkg.Runtime, can I register in my classloader as java.lang.Runtime?
As I said above, no you can't. A bytecode file has the classname embedded in it. If you attempt to "pull a swifty" by loading a class with a different name, the JVM will throw an Error.
And:
If not, then how can I replace the class? If the compiled package name has to equal the request referenced naming, then can I modify the .class file to to match, or perhaps compile it as if it were in the java.lang package?
That's what you would have to do. You need to name the class java.lang.Runtime in the source code and compile it as such.
But what I meant by my advice above is that you should use do the virus checking in the class loader. Forget about trying to replace / modify the behaviour of Runtime. It is a bad idea for the reasons I listed above.

Is there any class to diagnose invoked method in a java class?

I need to diagnose all invoked methods in a class(either declared in the class or not) using it's source code. Means that give the class source code to a method as an input and get the invoked method by the class as the output. In fact I need a class/method which operates same as java lexical analyzer .
Is there any method to diagnose all invoked methods ?
of course I tried to use Runtime.traceMethodCalls(); to solve the problem but there was no output. I've read I need to run java debug with java -g but unfortunately when I try to run java -g it makes error. Now what should I do ? Is there any approach ?
1) In the general case, no. Reflection will always allow the code to make method calls that you won't be able to analyze without actually running the code.
2) Tracing the method calls won't give you the full picture either, since a method is not in any way guaranteed (or even likely) to make all the calls it can every time you call it.
Your best bet is some kind of "best effort" code analysis. You may want to try enlisting the compiler's help with that. For example, compile the code and analyze the generated class file for all emitted external symbols. It won't guarantee catching every call (see #1), but it will get you close in most cases.
You can utilize one of the open source static analyzers for Java as a starting point. Checkstyle allows you to build your own modules. Soot has a pretty flexible API and a good example of call analysis. FindBugs might also allow you too write a custom module. AFAIK all three are embeddable in the form of a JAR, so you can incorporate whatever you come up with into your own custom program.
From your question it is hard to determine what is exactly problem you're trying to solve.
But in case:
If you want to analyze source code, to see which parts of it are redundant and may be removed, then you could use some IDE (Eclipse, IntelliJ IDEA Community Edition etc.) In IDE's you have features to search for usages of method and also you have functionality to analyze code and highlight unused methods as warnings/errors.
If you want to see where during runtime some method is called, then you could use profiling tool to collect information on those method invocations. Depending on tool you could see also from where those methods were called. But bare in mind, that when you execute program, then it is not guaranteed that your interesting method is called from every possible place.
if you are developing an automated tool for displaying calling graphs of methods. Then you need to parse source and start working with code entities. One way would be to implement your own compiler and go on from there. But easier way would be to reuse opensourced parser/compiler/analyzer and build your tool around it.
I've used IntelliJ IDEA CE that has such functionalitys and may be downloaded with source http://www.jetbrains.org/display/IJOS/Home
Also there is well known product Eclipse that has its sources available.
Both of these products have enormous code base, so isolating interesting part would be difficult. But it would still be easier than writing your own java compiler and werifying that it works for every corner case.
For analyzing the bytecode as mentioned above you could take a look at JBoss Bytecode. It is more for testing but may also be helpful for analyzing code.
sven.malvik.de
You may plug into the compiler.
Have a look the source of Project Lombok for instance.
There is no general mechanism, so they have one mechanism for javac and one for eclipse's compiler.
http://projectlombok.org/

IntelliJ Doesn't Notice Changes in Interface?

[I've decided to give IntelliJ another go (to replace Eclipse), since its Groovy support is supposed to be the best. But back to Java...]
I have an Interface that defines a constant
public static final int CHANNEL_IN = 1;
and about 20 classes in my Module that implement that interface. I've decided that this constant was a bad idea so I did what I do in Eclipse: I deleted the entire line. This should cause the Project tree to light up like a Christmas tree and all classes that implement that interface and use that constant to break. Instead, this is not happening. If I don't actually double-click on the relevant classes -- which I find using grep -- the module even builds correctly (using Build -> Make Module). If I double-click on a relevant class, the error is shown both in the Project Tree and in the Editor.
I am not able to replicate this behavior in small tests, but in large modules it works (incorrectly) this way. Is there some relevant setting in IntelliJ for this?
What you have here is an interaction between a standard java issue and a standard IDEA behavior. Constant expressions like this are inlined in the class compilation (as per the Java Language Specification), so in fact the class referencing this constant did not change just because you removed the line (obviously) and there is no recorded dependency between the constant and the class anymore since it was inlined. This causes the compilation to not fail (the class wouldn't fail at runtime either if that was the only change - it will only fail when you do a clean build).
One way around that in IDEA is to do a Build->Rebuild Project when you have such a change. The other is in Settings->Compiler there is an Honor Dependencies on "Compile" command. This can adversely affect performance in large projects (hence it is disabled by default), but is supposed to solve this kind of problem.
The other part of this problem is that IDEA does not automatically recalculate all inspections on a change like that. It recalculates when you open a file. I'm not aware of a setting that makes IDEA do that. When you rebuild any problems found will get highlighted (up to where the compiler gave up), but the highlight won't go away until you open the class or recompile as well.

Categories

Resources