I came across the sum.misc.Unsafe class when reading the implementation of ForkJoinPool. But no source code or api docs were found in the JDK.
Where can I find the source code or api docs for the sun.misc.*
For Java source code, I usually go to GrepCode
While such code is available (see Binyamin's post) it is generally a very bad idea to write anything that needs such code.
First, you are not generally assured that any JVM has such a class available (only JVMs descending from SUN's codebase would contain non-published, non-standard, SUN specific libraries). Also, since these are not standard libraries, you can't really depend on them being present or unchanged in subsequent releases of the SUN JVM.
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.
Attempting to build some javadocs using the com.sun.tools.doclets. Existing code is referencing a class file
SourceToHTMLConverter.class
Found it in an older JRE
JRE\160_38\lib\tools.jar\com\sun\tools\doclets\internal\toolkit\util\
However all of the JRE7 that I have does not seem to contain this class. Does anyone know why?
That class isn't part of Java's public API. It's no longer part of the Java distribution. In general it's a very bad idea to rely on anything in the package com.sun, especially if it also includes internal in the package name. This is because they're not part of the public, documented API, and the developers make absolutely no promises about how much these classes will change from version to version.
If you rely on such classes, your code isn't guaranteed to be portable from one JVM to another (it may or may not run on IBM's JMV or on Android), or ever from one version to the next of the same JVM. They don't even promise not to change these out from under you between minor revisions.
As for your question about why it was removed: because they didn't feel the need to keep it anymore, so they got rid of it. Simple as that.
Don't use those classes. Stick to the public, documented API.
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.
Out of curiosity, I wrote an own simple implementation of Set for a special case (where the set of all possible entries is fixed, but it's no enum). It was actually quite easy, but obviously, my implementation is unusable without a lot of tests (and maybe even then, but that's another topic; it was mainly an exercise).
So is there any testsuite available I could use for unit-testing it?
Use the Guava SetTestSuiteBuilder.
https://github.com/google/guava/blob/master/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java
Examples:
https://github.com/google/guava/blob/master/guava-testlib/src/com/google/common/collect/testing/TestsForSetsInJavaUtil.java
It is released as part of "guava-testlib" in maven central.
Oracle refuses to open source the test suite for java, this is the heart of a debate between the OSS community and Oracle.
See here for more info:
http://arstechnica.com/open-source/news/2010/12/apache-resigns-from-jcp-in-protest-of-oracle-governance-failures.ars
So I doubt there is anything you can do to verify you conform to the standard.
Here's an excerpt:
The heart of the issue is that Apache can't certify that its open source Java implementation—called Harmony—conforms with the Java language standards because Oracle refuses to supply the necessary test suites under a suitably open license. Oracle's position on the issue falls afoul of JCP policies, which stipulate that standards and other relevant materials must be freely redistributable and made available under terms that are conducive to enabling third-party open source implementations.
This conflict has been a subject of considerable friction for quite some time, because Sun similarly denied the ASF appropriate access to the test suite prior to Oracle's acquisition of the company. Oracle had initially sided with Apache in calling for the test suites to be published under open terms, but reversed its position after acquiring Sun. Oracle's approach to this issue suggested very strongly that the company would likely not be willing to fix any of the long-standing JCP governance problems that had arisen under Sun.
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