Patching a bug in the JDK for an individual application - java

I have established through another question that the problem I'm having with my JavaFX program is due to a bug in the JDK that is not going to be fixed anytime soon. I was even informed that the bug is in PrismTextLayout.
So having found the source code for this, how would I implement some kind of patch which would allow me to fix this bug for my application only. Obviously if I did fix the problem, I would contribute it back to a future JDK, but for now I just want a quick fix.
I thought a simple google search for patching the JDK, etc would turn up heaps of information, but actually, virutally nothing.
Can someone, if not explain how to patch, at least point me in the right direction for some documentation on this subject.

Patching a JavaFX class without actually building the whole JDK or JavaFX is quite easy. I did that for example for the class SVGPath some time ago.
Extract the class source from the source zip which is distributed with the JDK and add it to your project in the correct folder according to its package name. In my case this would be javafx/scene/shape/SVGPath.java.
Explicitly add ${JDK_HOME}/jre/lib/ext/jfxrt.jar to your classpath.
Run your program with the java options "-Djava.ext.dirs=".
This procedure is essential to be able to override the existing classes in jfxrt.jar.
That is it.

Related

At what point are Native Modules compiled in a React Native app (with Expo)?

Are the underlying Native Modules compiled when they are installed from NPM, or are they compiled when the App is run (i.e. bundled)?
I don't think it's likely that they are compiled when they are installed from NPM as that would require you to have the appropriate compilers on your computer at the time of installation (which I didn't).
On top of that, I can't find any files that appear to be the result of a compilation.
However, the reason that I'm not sure, is that changes to the Native code don't seem to be reflected in the final React Native app.
I'm trying to implement a feature that is missing in an NPM package, so to familiarize myself with the package, I've been tinkering around with the Native code.
However, I can change whatever I want, but the changes don't seem to do anything in the final application.
I went so far as to completely delete all of the Native code (the android and ios folders) from the given package and then cleared my cache (on both the Expo bundler and on the Expo client), but still nothing happened; somehow the application still seemed to ignore what should have been an obvious error (i.e. missing files).
Does this have something to do with the fact that I'm using Expo? Are the changes being ignored, because the code is being read from a cache somewhere?
Am I just fundamentally misunderstanding something?
Any help would be much appreciated.
P.s. My end goal is to be able to modify the aforementioned NPM package, so if it's not possible to modify a Native Module directly, can someone enlighten me as to the correct way to do so? Thanks.
For those of you who may be in a similar situation, it seems that you are unable to modify Native code with Expo unless you eject your app or you use vanilla React Native.
From what I gather, the reason for this is that every Native module that is compatible with Expo, comes pre-bundled with Expo (this includes modules that the Expo team made as well as modules that other people made but the Expo team included).
This means that unless you can get the maintaner of an Expo-compatible Native module to release a new version of their package with your changes applied to it, Expo will not pick up your custom changes.
Even then I can't guarantee it will work, as I don't know whether or not each release of Expo is limited to the versions of the Native modules that it contained at the point of it's release.
If you need more information, it would probably be best to try to contact one of the Expo developers on social media or on the Expo forums.
Here are some additional links. They may go dead eventually, but I'll include them anyways:
My question on the Expo forums
My question on Reddit

Understanding Deployment on Java 9+

After ignoring Java updates for quite some time, I now want to move on from the somewhat shady Java 10.0.2 Runtime I found somewhere to Java 13. As it turns out, Oracle stopped the "monolithic" JRE philosophy after Java 8 and I can't seem to find any definitive answers to my questions on how I'd go about deployment.
Here's what I think stays the same:
IDE (eclipse) workflow mostly stays the same
If I want to use the program myself, I can compile it to a .jar that will run on the JVM that comes with the JDK, just like with a Java 8 runtime
Now, here comes the tricky part I can't wrap my head around: Deployment on other machines
Create a module-info.java that lists the dependencies of that program
Compile a .jar as always using the eclipse dialogue
Use jlink to create a runtime image for that program to ship alongside
...But what now?
How are these images making the program work? I read that they're some sort of small JRE for that program alone, which would remove the need for Java to be installed on the target system, but how would that be cross-platform?
Or are they some sort of "patch" to the JRE that is available to download from the official site? That would explain why that is still being updated, but it wouldn't remove the need for Java to be installed on the target machine.
TL;DR:
Is there anything wrong with my understanding so far?
How do jlink-ed runtime images work?
How are they cross-platform?
Does the target machine still need any sort of pre-installed Java-related software e.g. a runtime / the runtime provided in the link?
Thank you very much for reading through my wall of text and thank you in advance for the answer!
EDIT: Made the point of question four clearer.
All my questions have been answered by Slaw in the comments to the original question, so I'll sum them up here in this answer.
My understanding so far is correct
jlink creates a mini-JRE with the modules the program needs, as specified in module-info.java
They're not, one would need to e.g. Linux-JDK to create a linux-specific version etc.
All files needed to run/interprete the program are contained in the runtime image
Also thanks for the extr info! I'll make sure to look into JMOD, and from what I read about jpackage, it's something to be very excited for.

Compiling this OCR Library Code

I came upon this simple Library that someone wrote in java GetImageText.java for OCR in images so i tried compiling it on my Ubuntu via terminal but i get several error as shown below in this paste :
Compilation Errors
Can Someone help me with it , it is absolute necessity that i test this code , its explanation can be found here
I think the problem is that i do not have com.sun.image.code.jpeg in my system, although java is definitely installed. Although I am not sure how to import this package without using an IDE.
The problem is that the library you are trying to recompile depends on INTERNAL classes1. Portable libraries are not supposed to do that!
What has happened is that the class has been removed or replaced. This happens from time to time, and that is the reason that people are not supposed to write code that depends on INTERNAL classes.
Solutions:
Bug the authors of the library to fix the problem.
Figure out which version(s) of Java that the library supports, and stick with those.
Find an alternative library that supports the version(s) of Java that you need.
Non-solution: Compiling the library on an older version of Java and running on a newer one is likely to fail. The class needs to be present at runtime, as well as at compile time.
1 - Anything in the "com.sun" tree counts as INTERNAL. Sometimes people have no choice but to have such a dependency. However, they still needs to deal with the potential consequences for portability.

Which order? ProGuard + JWrapper + Launch4J

I understand that StackOverflow is geared towards answering specific questions and avoiding subjective opinion. I feel that my question(s) have only one correct answer and therefore I’m posting here.
I’ve created a Java desktop app (JavaFX) which I plan to distribute for commercial use. I’ve read that Java code is easily reverse-engineered so it’s critical to obfuscate using something like ProGuard. I’d like to package my app so that users double click a .exe (which they download from my site) and then an installer is run like any standard software does. This appears to be outside the scope of ProGuard, but I’ve found JWrapper and Launch4J which both seem to provide similar functionality. Both claim to wrap jars into Windows native executables, show splash screens, include JRE, but I'm confused where they differ.
Specifically, I need the following:
Installation Wizard (namely to place the exe somewhere safe + make shortcut on desktop, and also add the EULA somewhere).
Add EULA (End-User License Agreement) which specifies user’s limitations
Web updates for the app (JWrapper seems to provide this using URL + build path)
Ability to protect the app (somewhat) using licensing (License3j seems promising).
Their features can be found here and here but only JWrapper mentions the ability to perform web updates and mentions desktop shortcuts (which I assume can also write a EULA.txt somewhere).
So, after I have finished writing code, in which order should ProGuard, JWrapper and Launch4j be applied? I’m guessing ProGuard first (to shrink, optimize and obfuscate) and then JWrapper and then Launch4j? Or only 2 of 3?
Feel free to also suggest additional methods, tools, or concepts which I may be missing. Thank you!
This question seems out of scope for Stackoverflow, but to answer it:
apply ProGuard first on your application, keeping the main method of your application
apply either launch4j or jwrapper (up to you to choose) on the jar processed by ProGuard

Tool for checking source for dependencies on specific Java versions

Is there a quick way (e.g. tool) to detect, from the source (or maybe even from compiled classes), which parts of an application call Java API methods that are only implemented in a specific Java version? (e.g. which parts of my app are Java6-specific)
I don't necessarily want to hop through all ClassMismatchErrors and avoid the trial-and-error-method. Let's say I only want to document which parts of an application won't work if they were writte for, e.g., Java6 and I want to run it in a version 5 JDK.
Is there something like this? Google did not help this time, nor did I find any solution here (a rare case indeed:)
The Animal Sniffer might be helpful for this, especially its Maven plugin.
If I understand you correctly, what you're describing doesn't sound like a very good idea to me.
It sounds like you want to build some library on JDK 6 (specifying -target 1.5), but let it be run on JDK 5 and just have certain classes or methods here and there just not work (because they needed a Java6-only API). I wouldn't do this. A method which should work might still trigger a class to be loaded which itself contains some reference to a class that's new in Java 6, and an Error will be thrown.
It's much better if you just choose which version is your minimum supported version and live with that.

Categories