Drawbacks
Disk footprint. Java bytecode has been designed for compactness, so it has a much higher level than a typical CPU instruction set.
Expect that an executable produced by an AOT compiler will be 2-4
times larger than the original jar file.
Dynamic applications. Classes that the application loads dynamically at runtime may be unavailable to the application
developer. These can be third-party plug-ins, dynamic proxies and
other classes generated at runtime and so on. So the runtime system
has to include a Java bytecode interpreter and/or a JIT compiler.
Moreover, in the general case only classes that are loaded by either
system or application classloader may be precompiled to native code.
So applications that use custom classloaders extensively may only be
partially precompiled.
Hardware-specific optimizations. A JIT compiler has a potential advantage over AOT compilers in that it can select code generation
patterns according to the actual hardware on which the application is
executing. For instance, it may use Intel MMX/SSE/SSE2 extensions to
speedup floating point calculations. An AOT compiler must either
produce code for the lowest common denominator or apply versioning to
the most CPU-intensive methods, which results in further code size
increase.