Java Doclet API change for jdk 8 - java-8

I am a newbie to Java. I was trying to upgrade to jdk 1.8 and found the following errors on doing a "gradle test":
/u01/sv/home/sv900t1/sv_test/Test_Suites/SeleniumLibraries/src/main/java/com/csgi/svtest/selenium/CustomWriter.java:57: error: cannot find symbol
h2("Class "+classDoc.toString());
^
symbol: method h2(String)
location: class CustomWriter
/u01/sv/home/sv900t1/sv_test/Test_Suites/SeleniumLibraries/src/main/java/com/csgi/svtest/selenium/CustomWriter.java:58: error: cannot find symbol
printHyperLink(classDoc.toString()+".html","","Class description<br>",true);
^
symbol: method printHyperLink(String,String,String,boolean)
location: class CustomWriter
I referred to http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java/
and http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java/
(our code imports this: import com.sun.tools.doclets.formats.html.SubWriterHolderWriter;)
and found that many apis like h2(), printHyperLink(), hr(), table(), tableHeaderStart(), tableHeaderEnd(), tableEnd(), pre(), strong(), preEnd(), ul(), print(), li(), ulEnd(), printHtmlHeader(), center(), today(), printTop(), navLinks(), printBottom() and printBodyHtmlEnd() have been removed.
Is there a quick workaround that can enable us to bypass the symbol errors?
Or should we replace the missing apis with existing ones. This looks like a lot of work to me - being an entrant. Are there any existing examples on how to do that? I have searched the internet a lot, but could not find anything useful.
The code in CustomWriter.java is for outputting a Javadoc page using custom System Test tags. Any help is appreciated - we are short on time.

Well here's the problem. The classes in the com.sun.tools.* packages should be treated as internal APIs. There are clear warnings in the Java documentation that say that you should not write code that against these APIs.
For example:
Why Developers Should Not Write Programs That Call 'sun' Packages
Closing the closed APIs
In Java 8, the header of the class that your code is trying to use says:
This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are subject to change or deletion without notice.
(The bolding is in the original!)
It didn't say that in Java 7 (ouch!) Indeed there are versions of the Javadoc FAQ which seem to encourage people reuse the standard doclet classes. Unfortunately, Oracle have decided to close off these classes, and have also made some breaking API changes which reinforces this, whether or not that was the intention of the changes
What can you do about it? Unfortunately, there is no easy solution:
Maybe you could find an truly open source Doclet codebase that you could modify.
Maybe you could find a commercial vendor or consultant who will do the work for you.
Or maybe you just "suck it up" and rewrite your code to work with the latest version of the (internal) APIs. And live with the possibility that you may need to take more pain in the future.
Or ... you could reinstall Java 7 on your build / test boxes and use it (just) for running your custom doclets.
UPDATE - It has been pointed out that the "rule" above is for sun.* packages. However:
The document doesn't say anything about com.sun.* packages, so it is not valid to infer that they fall into the same category as java.*, javax.* and others that are explicitly stated to be reserved for Java supported APIs.
There are other examples of com.sun.* packages that are explicitly stated to be NOT supported. For example, Oracle's "Compatibility Guide for Java 8" says things like this:
The com.sun.media.sound package is an internal, unsupported package and is not meant to be used by external applications.
The JDK internal package com.sun.corba.se and sub-packages have been added to the restricted package list and cannot be used directly when running with a security manager.
The apt tool and its associated API contained in the package com.sun.mirror have been removed in this release.
Conclusion, even if there is no explicit statement that com.sun.* packages are internal, Oracle is >>now<< treating them as internal when it suits them. In some cases, retrospectively.

Related

How to use #testable import for frameworks built via Carthage

I've already read answers for this question but I'm not satisfied.
Is there any possibility to use #testable for external libraries e.g. Alamofire, RxRealm (reason why I would like to do that is that, some classes are not open and in some cases it's not possible to create mock in unit tests without overriding real implementation).
Carthage doesn't build frameworks for testing. That's actually a good thing.
Library authors give guarantees on how the public interface of their software behaves, but have the freedom to change the private interface of it as much as necessary.
Instead of trying to subclass the implementation of your third party dependencies types to create test doubles for them, I would recommend to put a protocol in front of the subset of functionality you need from the library and only interact with the protocol in your production code.
If you have a particular case you'd like to test could you please update the question with it? I'd love to see if I can help.

Why Are My Dependent Frameworks Being Pulled In Twice?

[Note: This question is, I think, dealing with the consequences of what prompted this never answered question]
I have a workspace that includes both a framework target and an application target. When I run the application many messages of the following form come to the console: Class "C" is implemented in both "Binary1" and "Binary2". One of the two will be used. Which one is undefined.
Here is a sampling of those messages:
objc[65093]: Class FIRAIdentifiers is implemented in both /Users/Robert/Library/Developer/Xcode/DerivedData/GenerationOfNow-bmsridmvnbtgfiduzqqomicqvsns/Build/Products/Debug-iphonesimulator/VerticonsToolbox.framework/VerticonsToolbox (0x10804bd20) and /Users/Robert/Library/Developer/CoreSimulator/Devices/33628599-9570-4784-B324-DAC383435F75/data/Containers/Bundle/Application/26411B80-FB71-44E9-AA64-05FEF20B9F08/GenerationOfNow.app/GenerationOfNow (0x10674a150). One of the two will be used. Which one is undefined.
objc[65093]: Class FIRASearchAdReporter is implemented in both /Users/Robert/Library/Developer/Xcode/DerivedData/GenerationOfNow-bmsridmvnbtgfiduzqqomicqvsns/Build/Products/Debug-iphonesimulator/VerticonsToolbox.framework/VerticonsToolbox (0x10804bd70) and /Users/Robert/Library/Developer/CoreSimulator/Devices/33628599-9570-4784-B324-DAC383435F75/data/Containers/Bundle/Application/26411B80-FB71-44E9-AA64-05FEF20B9F08/GenerationOfNow.app/GenerationOfNow (0x10674a1a0). One of the two will be used. Which one is undefined.
objc[65093]: Class FIRAZeroingWeakContainer is implemented in both /Users/Robert/Library/Developer/Xcode/DerivedData/GenerationOfNow-bmsridmvnbtgfiduzqqomicqvsns/Build/Products/Debug-iphonesimulator/VerticonsToolbox.framework/VerticonsToolbox (0x10804bde8) and /Users/Robert/Library/Developer/CoreSimulator/Devices/33628599-9570-4784-B324-DAC383435F75/data/Containers/Bundle/Application/26411B80-FB71-44E9-AA64-05FEF20B9F08/GenerationOfNow.app/GenerationOfNow (0x10674a218). One of the two will be used. Which one is undefined.
All of the duplicated class definitions come from Firebase frameworks which were installed into my workspace via the Pod file demonstrated in this question. Here is a screen shot of my workspace's Navigator:
Notice that both the framework target (VerticonsToolbox) and the application target (GenerationOfNow) are referencing the pods.
It seems to me that the proper way for a framework to be built is that it should not embed whatever frameworks it is linked against. It should be the responsibility of whatever application uses that framework to pull in the other dependencies. And indeed, when I examine the build phases for the framework VerticonsToolbox there is no option for specifying embedded binaries whereas there is for the application GenerationOfNow.
So, I am at a lose as to how to proceed. I suspect that what is happening is a result of the things that are put in place when pod install is executed. Can anyone advise me?
BTW: Can anyone point me to a good write up on how Xcode builds, what the various settings are, what tools there are for examining the binaries, etc? With Xcode everything is fine until it isn't and then there is this big, mysterious soup of stuff. Jeez!

Can I use RxJava2 and RxAndroid in a single java class library?

I'm tasked with creating an SDK that can be consumed from both Android & Java applications using ReactiveX programming. I already have an android project using RxAndroid created, but now I need to extend it with RxJava2.
The question I'm facing is whether I should create 'regular' java class library and use it for both scenarios or create 2 separate packages (which would mean a lot of duplicate code + maintenance).
Is this even possible? And if so, is it a good practice?
whether I should create 'regular' java class library and use it for both scenarios
Yes. What I would do to start is simply change your Android library project to be a standard Java library and replace RxAndroid dependency by RxJava. Most code should still compile. Code which doesn't will mostly use schedulers provided by RxAndroid and can be changed to take Scheduler parameters.
Then create an Android Library project which depends on the Java Library and put the RxAndroid-specific code there.
As an addition to #AlexeyRomanov's answer, feel free to check out this library which could be used for both Android and Java projects: https://github.com/JakeWharton/RxRelay.
Its basically an extension to RxJava, but it might give you a solid idea where to go. Good luck!

How to compile jdk itself

I want to compile jdk itself. I mean, I want to modify String.class in jdk to see created string objects in the system. Is there any way to modify classes in the jdk? When I try to modify source by modifying rt.jar, I got the error.
java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:394)
at java.lang.System.initProperties(Native Method)
at java.lang.System.initializeSystemClass(Unknown Source)
Probably there is a signature problem.
That doesn't look like a signature problem. It looks like you changed something that's causing Hashtable to dereference a null pointer. Review the change you made and see why it's doing this. Recall that Java keeps internal references to String constants in some conditions. I'm guessing you broke one of those.
Is there any way to modify classes in the jdk?
Well, you can download, modify and build the OpenJDK releases of Java 6 from source. There's information on how to do this on the OpenJDK site.
But beware that changes to low-level Java classes (such as String) can have effects that are hard to a non-expert to understand. And the consequence could well be a JVM that fails in a way that makes println or printStackTrace() inoperative.
There is maybe another way: you download java.lang.String original source, doing your modifications and compile only this class.
When you start your main programm be aware when loading classes: first load your String class then the java runtime classes. Refer to the java manual and the -Xbootclasspath/p options to do it in the proper order.
When installing a JDK you may choose to install the sources as well. Do so. Or download the sources separately. Then
expand the src.zip and get the String.java file.
create a new project containing the String.java in package java/lang.
change it accordingly to your needs.
just compile it.
put the class into the bootclass path of your JDK. See More infos on Bootclassbath.
run your app.
java -Xbootclasspath/p:<changed String classpath> -cp <regular classpath> <your application main class>
But changing the JDK might not be a good idea and you are not allowed to ship a changed JDK (at least up to 1.6) due license restrictions.
And yes, your problem is most likely somewhere else. Remember select isn't broken ;-)

SecPKCS12Import() from Security.framework fails on OS X 10.6

When I attempt to use SecPKCS12Import() from the Security framework as provided by Mac OS X 10.6, the result code is always errSecUnimplemented, regardless of the arguments provided.
Furthermore, the linker is unable to find symbols for the constants relevant to this function declared in SecImportExport.h (i.e. kSecImportExportPassphrase, kSecImportItemIdentity, et al.).
What on Earth is going on with this library -- is the function implemented or is it not? Why can the linker resolve all other symbols in the framework, but not these? How should I convert a PKCS12-formatted binary blob to a SecIdentityRef or SecCertificateRef and SecKeyRef pair?
What am I doing wrong? I'm sure this is a PEBKAC issue. :-)
EDIT: I see that I was very unclear in my question. I'm aware that Security.framework is implemented, given that I am able to use the other functionality it provides without an issue. Given this, I'm fairly certain that I'm linking against the framework correctly, since if I remove the link, none of the symbols can be found -- as expected. When I relink the framework, all the symbols are found, with the exception of the constants relevant to SecPKCS12Import(), e.g. kSecImportExportPassphrase, kSecImportItemIdentity, etc.
Given that I cannot use these symbols, I passed in what could have been incorrect strings (#"kSecImportItemIdentity", etc.), but the error code returned was errSecUnimplemented. This led me to believe that perhaps this specific functionality has not been implemented.
I tried using the 10.5 SDK, but that didn't work, of course. :-)
EDIT: My import is just a regular #import <Security/Security.h>. For kicks, I tried #import <Security/SecImportExport.h> as well, but this effected no change. That said, the error is issued by the linker, not the compiler.
I ran dyldinfo -export Security.framework/Security to list the symbols exported by the library and found many of the new symbols, but kSecImportExportPassphrase and friends were conspicuously missing. This might explain why the linker cannot find the symbols. The symbol for SecPKCS12Import appears in the symbol table and I can call that with no issues, it's just the functionality does not seem to be there.
Security.framework is most certainly implemented — see the Security Reference Update which documents what has changed in the framework in 10.6 and prior. Since you know the headers to use, I assume you've already consulted the Security Framework Reference.
Are you sure you're properly importing and linking against the framework? (It's in /System/Library/Security.framework, so you shouldn't have to specify the path.)
Does the compiler issue warnings or errors stating that the symbols in SecImportExport.h are undefined? (If not, how do you know they're "declared but undefined"?)
When you say that this fails on 10.6, have you tried it on an earlier version of the OS successfully?
EDIT: Okay, since you're using other parts of Security.framework successfully, and the APIs and constants you're trying to use are 10.6 only, it doesn't seem like a linking issue. What do your import look like? Are you sure you're importing SecImportExport.h properly? The constants are declared just above the SecPKCS12Import() function, so if you get warnings for the constants, you should get one for the function being undefined as well.
EDIT: I have confirmed with a member of the team at Apple that works on Security.framework that this functionality is not currently implemented. Please file a bug to gripe about this at http://bugreport.apple.com against component Security (New Bugs), version X. Include the URL to this question in your report. Sorry there's not a better answer at the moment.
To my knowledge, Apple is great at partially implementing things or leaving no documentation. If you really can't find the real implementation you need, you can use OpenSSL to extract the blobs and then Security services to import them to a keychain or further process with Security/CDSA methods. That would get you going and you can ping the Apple dev connection with further questions, if you have the possibility.
Further, looking at /System/Library/Frameworks/Security.framework/Headers/SecImportExport.h on my 10.6.2 machine, I see references to PKCS#12 in the documentation of SecKeychainItemImport()
Search that file for "PKCS12" for further information.

Resources