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.
Related
Context
Running multiple version of the same library seems to be a usual need and there are many questions for this when dealing with versioned jar dependencies.
However, I have another constraint here: my code is part of a rolling-release MOAB where code has no version. I cannot depend on a older version of a library from the MOAB.
The use case of that question is being able to load different versions of the same code at runtime for compatibility.
Eg: GET /my/api/call?compat_version=42
I have to be able to provide several compatibility versions (ie code from version x that have not been changed). This must be the actual code that was running when version x was the current/latest version and not any kind of retrocompatibility trick.
Naive solution
The "obvious" way seems to duplicate the code for each version. For instance by having per-version packages:
com.me.thing.v1
com.me.thing.v2
com.me.thing.v3
...
and dynamically loading the code from the associate package upon the provided compat_version parameter by whatever technique. Let's suppose for know that all those versions share a common interface (API).
Challenge
I'd like to challenge that and maybe find a better option than the naive solution.
Since using the exact code from version x is a prerequisite, I don't believe I can get rid of the copy-paste (but please, tell me I'm wrong).
What technique would you suggest as a simple (but not necessarily easy) and robust implementation? Reflection? Dependency injection?
Is there a "good" pattern for doing such things? Is there any literature on that?
This was already an old problem when Java was developed, hence Sun's emphasis on binary compatibility (which existed for Solaris of course as well). This is the original guarantee offered by the platform- that you can upgrade the bits underneath and applications will continue to work, unmodified.
The way to run legacy code in the JVM world is to run the full legacy application.
Many segregation architectures have of course been developed over the years and reached various levels of maturity- like OSGI and many others before it- but there are edge cases upon edge cases and many failure modes.
Do not futz with multiple code versions within a single JVM. It was never a design goal and in environments where it matters only leads to pain.
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.
I want to keep only java util, io, nioand math packages and want to remove all other packages like java.sql and others from my JDK.
How can I remove them?
So if I write some program which import removed packages it will give
error package doesn't exist.
Use a SecurityManager instead of hacking the JDK
I'm going to give you the best answer I can.
Why you really shouldn't be doing what you want to do
When you're writing code, it is commonly agreed to develop that code in a way that is extendable. That is, your code can be plugged into other applications, or it can be changed and added to, very easily. Now with that principle in mind, let's review what happens when you delete the possible functionality of your program. Say you delete the SQL package, and in the future, you want a backend database to provide some persistence in your program. You're screwed.
The idea of Java, in fact I'd go as far as to say the major advantage of Java, is it's commonality, consistency and standardization of patterns. A getter is always a getter. A variable (that isn't a constant) starts with a lower case letter. Classes have a standardized way of being structured. All these things make developing in Java quite intuitive.
The JDK is part of that consistency, and to edit it is to really impact one of the major points of Java. It sounds like you want to implement your program in a different, more compact language.
Finally, you have no idea how the client may want to extend your project in the future. IF you want to have some repeatable business from the client, and generate a good reputation at the same time, you want to design your code with good design practise in mind.
There is no such tool, AFAIK.
Removing stuff from the Java libraries can be technically tricky, 'cos it can be difficult to know if your code might directly or indirectly use some class or method.
There are potentially "licensing issues" if you add or remove classes from a JRE installer, and ship it to other people.
Concerning your proposed use case.
If you are building this as a web application, then you are going to have a lot of difficulty cutting out classes that are not needed. A typical webapp server-side framework uses a lot of Java SE interfaces.
If you accepted and ran code someone who wanted to try and bring down your service, they could do it without using only the Object class. (Hint: infinite loops and filling the heap.) Running untrusted code on your server is a bad idea. Period.
Think about the consequence for someone trying to run legitimate code on your server. Why shouldn't they be allowed to use library classes / methods? (I'd certainly be a bit miffed if I couldn't use "ordinary" library classes ...)
My advice would be reconsider if it was a good idea to implement such a service at all ... given the risks, and the difficulty you could have if your safeguards were ineffective. If you decide to proceed, I advise running the untrusted code within the JVM in a security box. As a second level of defence in case Java security is compromised, I'd recommend running the service "chrooted" or better still in an isolated virtual machine that can be turned off if you run into problems.
I am starting on an enhancement to an existing Java applet where I let the user hit a link in a menu item, and open a page in his/her default browser. Some of our deployed code is in Java 1.4, while the majority of it is in Java 5. This prevents me from using the Desktop API in Java 6. It looks like the easiest way to solve the problem is to integrate BrowserLauncher2 into the application.
The wrinkle is that the existing code includes an early version of BrowserLauncher.java (version 1.4b1 (Released June 20, 2001)). Unlike the original, BrowserLauncher2 is more than just one class. It appears to have a ton of enhancements of which I'd like to take advantage.
I think I will use the newer release for my needs, and just drop the references to the old version in the legacy code. I have a pretty good suite of existing unit tests on the old code, and will do some functional testing on the code where I make the swap.
Does anyone who has already been down the upgrade path from older versions of BrowserLauncher have any advice on potential gotchas?
Well, that's what you get for asking such an obscure question. Instead of letting an unanswered question sit abandoned, I'll share what I've learned.
The BrowserLauncher class in BrowserLauncher2 has deprecated the old static openURL(String) method. In addition, while the old method threw an IOException, the new one throws a different set of exceptions.
It's therefore necessary to rewrite your catch blocks, and is probably a good idea to convert static calls to openURL(String) into calls to methods on an actual BrowserLauncher object.
Given the improvements in BrowserLauncher2, however, it's probably worth it.
What is classpath hell and is/was it really a problem for Java?
Classpath hell is an unfortunate consequence of dynamic linking of the kind carried out by Java.
Your program is not a fixed entity but rather the exact set of classes loaded by a JVM in a particular instance.
It is very possible to be in situations where the same command line on different platforms or even on the same one would result in completely different results because of the resolution rules.
There could be differences in standard libraries (very common). Libraries could be hidden by one another (an an older version may even be used instead of a newer one). The directory structure could mess resolution. A different version of the same class may appear in multiple libraries and the first one encountered will be used, etc. Since Java, by specification, uses a first-encountered policy, unknown ordering dependencies can lead to problems. Of course, since this is the command line and it is part of the spec, there are no real warnings.
It is very much still a problem. For example on Mac OS the horrible support from Apple means that you machine ends up with several JVMs and several JREs, and you can never easily poart things from place to place. If you have multiple libraries that were compiled against specific but different versions of other libraries, you coulld have problems, etc.
However, this problem is not inherent in Java. I remember my share of DLL hell situations while programming windows in the 90s. Any situation where you have to count on something in the file system to assemble your program rather than having a single well defined executable is a problem.
However, the benefits of this model are still great, so I'm willing to tolerate this hell. There are also steps in the right direction on the side of Sun. For example, Java6 allows you to simply specify a directory with jars rather than have to enumerate them.
BTW: Classpaths are also a problem if you are using an environment that uses a non-default classloader. For example, I have had a lot of problems running things like Hibernate or Digester under Eclipse because the classloaders were incompatible.
Classpath/jar-hell has a couple of escape hatches if they make sense for your project:
OSGi
JarJarLinks
NetBeans Module System - Not sure if this is usable outside of NetBeans
Others?
I think "classpath hell" refers to the time when the classpath of a Java app could only be set by using the CLASSPATH environment variable. This led to many applications requiring changes to the global system configuration (different for each OS), version conflicts between applications, and general confusion.
This is a somewhat more concrete example:
When two libraries (or a library
and the application) require different versions of the same third
library. If both versions of the third library use the same class
names, there is no way to load both versions of the third library with
the same classloader.
Take a loot at http://en.wikipedia.org/wiki/Java_Classloader#JAR_hell for more examples.
There's lot of good stuff here http://mindprod.com/jgloss/classpath.html and http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html
I've only had issues with classpaths when I am not setting is myself using -cp. Trying to figure out how your third-party software sets their classpaths can be a pain at times.