52

I have seen many apps that take instrument classes and take -javaagent as a param when loading also put a -noverify to the command line.

The Java doc says that -noverify turns off class verification.

However why would anyone want to turn off verification even if they are instrumenting classes?

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
pdeva
  • 43,605
  • 46
  • 133
  • 171

7 Answers7

54

Start-up time, I'd say. Verification that classes are correct takes some time when the class is loaded. Since classes might be loaded in a lazy fashion (not on app start, but when being used for the first time), this might cause unexpected and undesired runtime delays.

Actually the class does not need to be checked in general. The compiler will not emit any invalid bytecode or class construct. The reason for verification is that the class may be build on one system, get hosted online and is transmitted to you through the unprotected internet. On this path, a malicious attacker might modify the bytecode and create something the compiler might never create; something that can crash the JVM or possibly circumvents security restrictions. Thus the class is verified before it is used. If this is a local application, there is usually no need to check the bytecode again.

Mecki
  • 125,244
  • 33
  • 244
  • 253
  • 3
    In case someone wonders to this answer in 2013+, check Arian's answer as this one is not correct. https://github.com/spring-projects/spring-loaded#readme – Pavel Horal Oct 12 '13 at 00:39
  • 6
    @Pavel There is nothing incorrect about my answer. Just because there exists another reason why disabling byte code checks is a good idea doesn't make may answer any less correct. SpringLoad is just ONE existing JavaAgent and just because this one may produce invalid byte code doesn't mean that all JavaAgents do so, as no JVM has to work correctly when getting fed invalid byte code, that's why most software in the world only produces valid byte, making Arian's argument void. – Mecki Nov 08 '13 at 20:33
  • 1
    Don't get me wrong - you have well explained how `noverify` works and why it can speed up class loading. However the question is pretty specific about its connection to `javaagent`. Are you saying that e.g. JRebel uses this JVM argument in every integration manual just for the sake of performance? – Pavel Horal Nov 08 '13 at 21:07
  • 1
    The question is not about JRebel or SpringLoad either, so what relevance does it have why JRebel or SpringLoad use it? – Mecki Nov 11 '13 at 16:50
50

When it is used in conjunction with -javaagent, it is most likely not for performance reasons, but because the agent intentionally creates "invalid" bytecode.

It should be noted that invalid bytecode might still execute fine, because some of the verification rules are quite strict. For instance, this must not be accessed in a constructor before the super-constructor was called, because the variables are not initialized at this point. But there still might be other things you want to do (see the JRebel example). Then, you use -noverify to circumvent that rule.

Cephalopod
  • 14,632
  • 7
  • 51
  • 70
5

Debugging! In fact that's what I'm doing now, and how I stumbled across this question. At Terracotta we do a lot of bytecode instrumentation, and sometimes it helps to turn off the verifier as we debug our class adapters, so we can see where exactly they fail at runtime.

You're right, we want the verifier to remain on in production.

Scott Bale
  • 10,649
  • 5
  • 33
  • 36
5

Using JRebel without -noverify will give this warning on startup:

JRebel: '-noverify' missing, changing/adding/removing constructors will not be enabled!

So appears that -noverify allows bytecode re-instrumentation to do some things which would otherwise not be possible.

Esko Luontola
  • 73,184
  • 17
  • 117
  • 128
3

Start up time used to be a bit of an issue. However, verifiers are now faster, as are processors. Code compiled with JDK6 javac will by default include extra information to make the verifier step faster. Apache Harmony just uses a much faster verification algorithm.

Some very old versions of javac produced incorrect bytecode. Indeed the Sun PlugIn still includes fix-up code to make some broken class files verify.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
2

The new verifier that is introduced in JAVA 6 is very complicated to process for code manipulations.

Take a look at this: http://chrononsystems.com/blog/java-7-design-flaw-leads-to-huge-backward-step-for-the-jvm

and the related bug report: http://bugs.sun.com/view_bug.do?bug_id=8009595

Aykut Kllic
  • 898
  • 9
  • 14
0

It disables bytecode verification at runtime. When this flag is set, the JVM skips the verification step that ensures that the bytecode is like complete and also skips checks for upcoming exceptions that will/might occur when the code is ran. An example would be this:

public class Example {
    public static void main(String[] args) {
        int x = 10;
        int y = 0;
        int z = x / y; 
        System.out.println("z = " + z);
    }
}

With the noverify flag, the code wont execute because the jvm expects java.lang.ArithmeticException but with the flag it will execute.

pvpb0t
  • 33
  • 6