Use of -noverify when launching java apps

2019-02-07 17:18发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

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.



回答5:

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.



回答6:

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