The Java bytecode language has the JSR instruction.
None of the code I've compiled with the Java 7 compiler uses this instruction.
However, sometimes Java binaries I've downloaded do use it, although rarely.
I'd be interested to know what compilers do use the instruction, and what Java code constructs would cause them to use it.
Edit this is not a duplicate as it refers to the JSR bytecode instruction and not a Java Specification Request
The JSR instruction is actually not even allowed in Java 7 classfiles. It is only allowed in version 49.0 or earlier classfiles, corresponding to Java 5 or earlier. In practice, it fell out of use long before that.
The JSR/RET mechanism was originally used to implement finally blocks. However, they decided that the code size savings weren't worth the extra complexity and it got gradually phased out.
I don't know the exact versions since I can't find any compilers that old, but based on discussions I found online, it seems that the transition happened in the Java 1.2-1.3 era, with different compilers switching at different times. I have never seen a legitimate classfile from one of these old compilers, but you never know when it could happen.
In practice, the only use of JSR I've seen in the wild is for obfuscation. For example, Zelix Klassmaster used to use it for its string decryption code. I've also used it in several of my own Java crackmes.
According to the JVM specification:
In Oracle's implementation of a compiler for the Java programming language prior to Java SE 6, the jsr instruction was used with the ret instruction in the implementation of the finally clause
Related
For a long time, I have been an application developer in java. Recently, Java and JVM specification piqued my interest. I wanted to know more about some of the internals of java on topics that eluded me for a long time.
I tried searching for ThreadLocal or Annotation Processors in those documents and I couldnt find them. Is there a reason behind dearth of information regarding them? I thought Threadlocal atleast was part of Java packages?
Are specifications not encyclopedias that I imagined them to be?
They are fairly huge documents, so I might have missed them completely
https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf
https://docs.oracle.com/javase/specs/jls/se8/jls8.pdf
Why aren't ThreadLocal or AnnotationProcessor defined in the Java Language Specification (JLS)?
Because they are specified somewhere else.
The specification for ThreadLocal is in the javadocs:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ThreadLocal.html
The specifications for annotation processors are also in the javadocs. Start here:
https://docs.oracle.com/en/java/javase/11/docs/api/java.compiler/javax/annotation/processing/package-summary.html
https://docs.oracle.com/en/java/javase/11/docs/api/java.compiler/javax/annotation/processing/Processor.html
In general, the JLS only specifies the Java programming language itself. Other aspects of the Java environment such as the Java class libraries, the JVM specifications, the Java tool specifications, and many other things are specified (or described) in various technical notes, white papers and JSRs or JEPs.
In general, all of this information is on the public web, and can be found using Google and intelligently chosen search terms. For example, I got the javadocs of ThreadLocal in Java 11 by Googling for javadoc ThreadLocal java 11.
However, if you are looking for internal documentation (e.g. some design document that explains how ThreadLocal is implemented) you are unlikely to find anything ... beyond the OpenJDK source code itself. But the source code is freely available and (generally speaking) well commented. Google for the version you are looking for; e.g. openjdk source code java 11.
The Java bytecode language has the JSR instruction.
None of the code I've compiled with the Java 7 compiler uses this instruction.
However, sometimes Java binaries I've downloaded do use it, although rarely.
I'd be interested to know what compilers do use the instruction, and what Java code constructs would cause them to use it.
Edit this is not a duplicate as it refers to the JSR bytecode instruction and not a Java Specification Request
The JSR instruction is actually not even allowed in Java 7 classfiles. It is only allowed in version 49.0 or earlier classfiles, corresponding to Java 5 or earlier. In practice, it fell out of use long before that.
The JSR/RET mechanism was originally used to implement finally blocks. However, they decided that the code size savings weren't worth the extra complexity and it got gradually phased out.
I don't know the exact versions since I can't find any compilers that old, but based on discussions I found online, it seems that the transition happened in the Java 1.2-1.3 era, with different compilers switching at different times. I have never seen a legitimate classfile from one of these old compilers, but you never know when it could happen.
In practice, the only use of JSR I've seen in the wild is for obfuscation. For example, Zelix Klassmaster used to use it for its string decryption code. I've also used it in several of my own Java crackmes.
According to the JVM specification:
In Oracle's implementation of a compiler for the Java programming language prior to Java SE 6, the jsr instruction was used with the ret instruction in the implementation of the finally clause
So up until about 6 months ago, most of my work (big graph processing) consisted of Python and C++. Up to that point, and even now, I had not written any Java whatsoever.. I had seen the language and was familiar with the syntax (having come from a C/C++ background), and liked the idea of the JVM, but never actually written any substantial amount of Java.
When I picked up Scala, I loved it, OOP and functional programming features all in one, and it being on the JVM was great. I've been constantly striving to improve my Scala and have been playing with Akka, and still loving it. However, at times, perhaps it is just me overthinkng it, but I feel I should learn some more about Java and/or the JVM.
I've heard from many that Scala should be considered a separate language from Java, much like C++ to C. Perhaps you may feel the same way, and perhaps learning Java is more or less disjoint from learning Scala, but I'm feeling learning more about the JVM (e.g. JIT compilation, type erasure) would be helpful?
Thoughts?
The JVM executes Bytecode and it is definately helpful to know how this works, just as it is sometimes helpful to know how C/C++ method invocations work or how classes are initialized; because sometimes it matters and cannot be abstracted away.
Java is the prime language for the JVM, and it is helpful to be able to read Java to some extent if you need to use Java classes directly. And this may happen quite often; only a few examples:
you need to use some third party Java library (and there are tons)
working with Properties
you need to do something special in Swing which is not supported by the Scala-Swing wrapper
also sources explaining stuff for 1) will most probably use Java examples
But my advice is not to study it in advance - you'll pick it up when you need it.
Buy this book now: Java Performance. It was only released last October and is a treasure trove of information for anyone who wants to understand the JVM. If you're going to be a Scala developer, you must understand garbage collection and JVM runtime parameters at the very least.
Off top of my head
primitives, autoboxing, and how java arrays are special;
erasure and manifests
how logically tail recursive calls in scala source are compiled
installing -client, -server on your platform and when you want to try 32 bit: e.g. JAVA_HOME and "Java preferences" in OS X. I think openJDK should work anywhere you use same version of Oracle JDK, but IntelliJ warns you to use only official Oracle JDK. I've seen very isolated reports that 3d graphics libs have had problems with openJDK, and also parts of openJDK like the fonts have licensing issues.
setting classpaths in REPL, as compiler option, and in SBT
Hotspot switches, XMX, XMS (heap settings), most common garbage collectors, inlining method calls
java.util.concurrent
possible binary compatibility issues with java and scala code compiled in JDK 6 and 7.
I don't know exactly what you need, but there are several similar questions on SO, look it.
Understanding JVM Better
Understanding the Sun JVM
Also, here good articles for Java Memory Model
Java theory and practice: Fixing the Java Memory Model, Part 1
Java theory and practice: Fixing the Java Memory Model, Part 2
My thought it's better to dig in Java language, write some code, read Java-specific books for better understanding how all things works.
There are a lot of tools surrounding the JVM. If you want to understand how your programs are running (for performance or other reasons) then it's worth being au fait with these. Two useful tools are:
jstack
visualvm
Both are particularly useful for monitoring and interrogating long-running processes.
I think you will know more about JVM when you program Scala. I mean you will have more questions like 'Why this solution is slow and that is fast?' - one way to answer this question is to check the bytecode
JSR-335 is said to come soon along with Java 8. It brings i.e. support for closures and virtual extension methods.
I wonder if there is any particular support for this on the JVM level?
If so, can we hope for speed improvements in JVM-based functional languages that provide closures and extension-methods-like features (such as traits or implicits in scala)?
Edit:
reading this oracle presentation on Java 8 by Brian Goetz, it would appear that:
- closures don't require
- virtual extension methods do require
particular JVM-support.
Could this mean that in scala, some of the implicits, and traits could be reimplemented in a more efficiently way?
I don't think extension methods can be used to implement traits -- a method implementation can't call super on them (afaik -- I might be wrong), and the override semantics would be different. Furthermore, it would not cover fields, just methods.
There isn't anything JVM can do to help with implicits, because there's no inherent problem with them. They are normal instances passed as normal parameters. Looking them up makes the compiler slow, but JVM can't help with that either.
I don't see any of these features helping with anything in Scala, but that's almost moot, actually. Scala still generates JVM 1.5 bytecode with JVM 1.5 classfiles. You can turn on JVM 1.6 bytecode, which makes little difference. With Scala 2.10, 1.6 classfiles will be enabled on an experimental basis.
The reason for that is pretty simple: Java 1.7 runs 1.5 classfiles with 1.5 bytecode, but not the other way around. There's still a lot of people running older versions of Java, and that is unlikely to change.
So I don't see any Java 1.8 features in the radar, unless they bring a huge advantage. And, even then, they'll most likely be available for code compiled with Scala, but not on the Scala library itself. Likewise, unless it brings a huge advantage, I don't see libraries being made available in both versions.
I think the speed of Scala is very close to Java already. It is the dynamic typed jvm languages are slow (such as Groovy). And actually JDK 7 came out with the new feature invokedynamic for the purpose of improve those dynamic jvm language:
http://java.sun.com/developer/technicalArticles/DynTypeLang/
Where is exactly is the demarkation between a version of Java and the JVM?
I'm asking because of a recent 'educational' comment thread with a fellow SOpedian regarding the default buffer size of java.io.BufferedInputStream, which I see is 8192. (Has it always been 8192?) When thinking about just the API, it is clear to be what is what. But with the implementation of a java.* class...I just don't know.
This leads to two derivative questions:
Could BufferedInputStream's default buffer size change between versions of Java?
Could BufferedInputStream's default buffer size be different on various vendor's JVMs?
(Surely there are other similar examples, like in the implementation of various collections.)
Since the API specification of BufferedInputStream doesn't specify a value, it is entirely up to the implementation to choose one.
This means that the default buffer size can change between Java versions as well as between different implementations of the same Java specification.
It's pretty much the same in other areas: the real specification is the documentation (i.e. JLS, JVM Specification and API specification, or rather the corresponding JCPs).
Everything else (i.e. everything you can see from looking at the source) is an implementation detail and depending on it is a bug.
"Java" is a language and API specification. The JVM is covered by a completely different specification, which describes the format of a class file and the way that bytecode works.
To be called "Java," an implementation must pass a series of tests defined by Sun and the JCP. These tests say nothing about the internal implementation of the API or JVM.
The implementation of the API can and does change between revisions, in response to bug reports and general cleanup.
Basically the line is the specification, which is mostly in the Java doc. The specification outlines a contract for the API and an implementation would have to honor that contract. What the contract does not specify would be up to the implementation.
Of course, in practice no specification is perfect, so there are practical details that get relied on even if they are not specified. Joel Spolsky has a good article on it, although in Java things are much better than in W3C.
Java is the language. There's a specification for that.
The JVM is a piece of software than can execute Java bytecodes.There's a specification for that.
There are many implementations of the JVM (Sun's, IBM's and various mini versions for phones etc.), and there are many implementations of Java.
The Java language may compile to bytecode, but it doesn't have to, it could compile to IL (for the .Net CLR) or to native code or to anything else.
The JVM does not have to run Java applications, see for example Jython and JRuby and many other examples