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.
Related
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
I'm writing a library that inserts already unit-tested example code (its source-code, output, and any input files) into JavaDoc, with lots of customization possibilities. The main way of using this library is with inline taglets, such as
{#.codelet.and.out my.package.AGreatExample}
{#.codelet my.package.AGreatExample}
{#.file.textlet examples\doc-files\an_input_file.txt}
{#.codelet.and.out my.package.AGreatExample%eliminateCommentBlocksAndPackageDecl()}
Since custom taglets (and even doclets) require com.sun, this means they're not nearly as cross platform as Java itself. (Not sure if this is relevant, but the word "javadoc"--and even the substring "doc"--is not in the Java 8 Language Specifications.)
I don't like the idea of writing a library that's limited in this way. So what do I do? My thoughts so far are that
In order to take advantage of the existing javadoc parser, I stick with the com.sun taglets. However, I make this reliance on com.sun as "thin" as can be. That is, I put as little code in the taglet class as possible, leaving the bulk of the code elsewhere, where there is no reliance on com.sun.
I work towards creating my own parser, which only searches for my specific taglets. This is a pain, but not too horrible. You iterate through the lines of each Java source file, searching for \{#\.myTagletName (.*?)\}. Once you capture that text, it's pretty much the same as the code within the com.sun taglet.
This parser would have to be run before executing javadoc, and would therefore require a duplicate directory structure. (1) your original code, with the unparsed custom tags, (2) the duplicate of that code, with parsed-output. I'd copy all code to the duplicate directory, and then parse only those Java files known to have these taglets (classes that are "registered" in some way with the parser).
Is this a reasonable approach? Is there a more cross-platform javadoc/taglet parser out there already, so I don't have to roll my own? Is there anything cross-platform that is taglet-like already out there? Is JavaDoc itself not cross platform, or just custom taglets and doclets?
I'd like a rough perspective on how many people I'm locking out of my library because of this decision (to use inline taglets), but mostly I'm looking for a long term solution.
(Despite my Java 8 link above, I'm using Java 7.)
Credit to #fge for the taglet suggestion, which is more elegant than my original idea, and to #Michael for the ominous-but-helpful com.sun warnings.
At first, note that there is a difference between sun.* and com.sun.* dependencies. The sun.* namespace contains classes that implement Oracle's Java Virtual Machine. You should not use such dependencies because the Oracle JVM's internal API can change in future releases and because this namespace may not be provided by other, non-Oracle JVM implementations. (In practice, even Android's JVM ships with one of the more widely used sun.* classes.)
Then there is the com.sun.* namespace which was used by Sun Microsystems for implementing its Java applications. An example for legal use of com.sun.* dependencies is Sun's Jersey framework which was originally deployed in the com.sun.jersey.* namespace. (For the sake of completeness, note that recent Jersey versions are deployed in the org.glassfish.jersey.* namespace beginning with version 2.0 which is incompatible to the Jersey 1 API.) For further reference, note how Oracle does not even mention the com.sun.* namespace when discussing the problems that are imposed by using the sun.* namespace. Also, see this related question on Stack Overflow.
Therefore, using com.sun.* dependencies is a different deal compared to sun.* dependencies. By using com.sun.* classes, you rather lock yourself to a specific library's API, not to a specific JVM. For example, you can avoid direct use of the com.sun.jersey.* namespace by using the standardized JAX-RS javax.ws.rs.* namespace. In this sense, com.sun.* dependencies are product specific and proprietary and must not be confused with Java's standardized APIs which are usually found in the javax.* namespace.
If I was you, I would stick with the taglets which is a mature and recognized implementation. Oracle is pretty determined not to break APIs (otherwise, they would probably also move the taglets to com.oracle.*) and I see no reason why they would suddenly change the taglet package structure. And if they would, you merely need to update your tech. If your application breaks for a new Java release, your users will come looking for an update of your software. Because you do not run the taglet project, I agree with you that detaching your logic from a foreign API is in general a good idea as it is for any dependency. Also, using taglets for your use case pretty much recognizes the KISS and DRY principles.
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
I am helping edit and translate a programming class to English. When talking about the Java library, the initial translator is using the term Java "made-up" classes. So for a list of available Java interfaces, the document says something along the lines of
"Java comes with plenty made-up interfaces like List, Set and Collection."
This is a document for novice programmers and I want to be precise. My instinct is to use "built-in", as seen here.
I realize that this is not strictly a programming question. But I feel it is unlikely to be answered with precision by the English Language and Usage board. Whether to ask this sort of question of StackOverflow was discussed beforeand I tend to agree with the comments under the accepted answer. I hope that doesn't offend anyone.
Update: I eventually used a brief variety of phrases, inspired by the following passage in Joyce Farrel's Java Programming (6th Edition):
Of particular value is the Java application programming interface,
more commonly referred to as the Java API. The Java API is also called
the Java class library; it contains information about how to use every
prewritten Java class, including lists of all the methods you can use
with the classes.
Thanks to the responders.
Wiki calls it a standard code library, so I would write:
"Java comes with a standard code library providing interfaces and classes like List, Set, Collection"
Java Class Library
"Java comes with a huge standard library providing interfaces and classes like List, Set, Collection."
Technically, there is no difference between user-defined classes and classes bundled with particular Java runtime.
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