How to disallow a certain Java version in JNLP? - java-web-start

Sometimes there are serious regression bugs in Java which make our product unusable. So I would like to disallow the associated version, e.g. currently 8u161 and 8u162 (bug JDK-8195830).
How can I do so in JNLP? The docs only mention + as a wildcard. So is the only possible way to list all other Java versions instead? like
<java version="1.8.0_05"/>
<java version="1.8.0_11"/>
... until ...
<java version="1.8.0_151"/>
<java version="1.8.0_152"/>
?
Update:
So the result looks like this.
<java version="1.8.0_172+ 1.8.0_152 1.8.0_151 1.8.0_144 1.8.0_141 1.8.0_131 1.8.0_121 1.8.0_112 1.8.0_111 1.8.0_102 1.8.0_101 1.8.0_92 1.8.0_91 1.8.0_74 1.8.0_73 1.8.0_72 1.8.0_71 1.8.0_66 1.8.0_65 1.8.0_60 1.8.0_51 1.8.0_45 1.8.0_40 1.8.0_31 1.8.0_25 1.8.0_20 1.8.0_11 1.8.0_05"/>
Conclusion: In the end I decided not to provide any version constraints in the JNLP, because the popup says it recommends to start the application anyway – which is quite the opposite of what I have to tell the user.

The problems seems to be that *racle seems to have dropped support for loading and using earlier JREs except for the most up to date JRE.
Your approach seems to be the only pure JNLP-way as also suggested here.
You may also try to write it in one big line separated by spaces. The only thing which I would change is the order so that the highest is a the top.
"If several JREs are specified, this indicates a prioritized list of
the supported JREs, with the most preferred version first."
You may want to theck similar quesions posted here
A different approach to exclude a specific java version is to check it within your application.
public static void main(String [] args) {
String version = System.getProperty("java.version");
if("1.8.0_161".equals(version) || "1.8.0_162".equals(version){
//print an error dialog
}
else{
//continue normal flow
}
}
In a previous application I even went a bit further and had two different web applications: A "light" web application which was started before the actual application. This light web app nearly had no requirements regarding java version (even started with 1.4) and it would then check all the necessary requirements (Java Version, OS, RAM, CPU, files ...). Only after all went well the actual application would be started.

Related

How do I use JavaFX in Eclipse 2021-06 JRE x86_64_16.0.2

There are a couple postings on this topic, but I can't get this to work with the latest version of Eclipse. I am using the JRE that comes with 2021-06, the one it puts in p2, x86_64_16.0.2.
I have tried various configurations of User Libraries, Maven dependencies, setting PATH_TO_FX, searching Eclipse Marketplace for JavaFX-as-a-plugin, e.g.,
How do I use JavaFX 11 in Eclipse? (2.5 years old)
https://www.javatpoint.com/javafx-with-eclipse
https://www.tutorialspoint.com/javafx-with-eclipse
https://gluonhq.com/products/javafx/
On a couple more elaborate examples, a couple builds had a scattering of missing methods, which I assume is due to JavaFX being somewhat in flux or instructions being quite outdated. I can get a simple Hello, World to build with javafx-sdk-17.0.1 as a User Library (what I'm doing now) and also some of the other configurations. When I try to launch Hello, World with various build-able configurations, I keep getting
Error: JavaFX runtime components are missing, and are required to run this application
Well, I was a bit too quick. I kept playing around, and adding quotes in the VM arg seems to work,
--module-path="C:\Program Files\Java\javafx-sdk-17.0.1\lib" --add-modules=javafx.controls
If the project is not a module project, the Used Library goes on the Classpath in the project properties, Libraries tab. If it is a module project, it goes on the Modulepath,and the following module-info.java file must be in the src with this minimal information:
module <myProject> {
requires javafx.controls;
exports <myPackageContainingFXAppClass>;
}
I just don't get it why people prefer to search half of the internet for tutorials instead of just consulting the official documentation first. Here it is: https://openjfx.io/openjfx-docs/#IDE-Eclipse It seems to be the best hidden secret that there actually is documentation for JavaFX that one could start with.
I just did the test. Googling for "javafx documentation" gives https://openjfx.io/ as the first search result.
I use --module-path=${PATH_TO_FX} --add-modules=javafx.controls.
Obviously PATH_TO_FX needs to be defined in Preferences->Run/Debug->String Substitution.

How to debug JavaFX application with jdk14/javafx14/Eclipse v.2020-03?

I'm trying to run a JavaFX application to test some custom controls based on jdk14 and JavaFX14. My operating system is Windows 10, the IDE is Eclipse 2020-03, and I use m2e Maven plugin. The controls are exact copies of controls developed under jdk8 and JavaFX8; the earlier controls pass all tests, there was no problem with debugging.
There is no problem getting a test application to run using jdk14 and JavaFX14, but breakpoints are ignored regardless of whether I run in debug mode, or run mode, or whether I modify the Maven command from javafx:run to javafx:debug (that did NOT work) or to javafx:run#debug.
This issue seems to have been addressed several times in the context of a Netbeans IDE (see stackoverflow discussion, and I copied in the text from the modified plugin as suggested, but to no effect.
I have the following questions:
What must be done in order to debug a JavaFX application under the conditions described above?
Who is responsible for dealing with this? Eclipse? OpenJFX? Somebody else?
Based on the principle that whatever solution is developed, it should be as user friendly as the debugging process under jdk8 and JavaFX8 (i.e. before JavaFX and everything else got decoupled from Oracle), is it reasonable to expect that a solution along those lines will be available in the near future? Is anybody working on it now?
Thanks for feedback.

How to make an application to work with any Java versions?

I have created a Java project application in eclipse and i am using the JRE System Library[JavaSE-1.7].
when i make an executable jar file of the application then test it on different computers which have different Java versions. The problem is that the jar file only works on some of the computers because of the java version.
my question is: is there away to make the application to check the computer see which java version it has and just use that version instead of the java version that was used to implement the project? in other words can you make an application which is not java version dependent?
any suggestion is of great help.
thanks
Thanks for all the suggestions and comments. But i think i'll just stick with the java 7 version and let the user know that they need java 7 to run it.
No, there's no way to check that, not in the way I think you mean.
In fact, on the one hand you have the Java version in which you compile the class (which you can choose), and on the other hand the Java version (of the JVM) in which your application runs (which you cannot choose).
Well, I do believe there's a way to check the Java version through some method call or similar, but I don't think it would help you here, I mean that I guess you can't do something like:
if(java-7) {
//do try-with-resources
} else {
// do usual try-statement
}
As #skiwi suggested, make sure your application compiles against an older Java version, and you should be fine with JVMs of that version and beyond.
I'm not sure what's causing your ClassNotFound error, but it could be that the JVM checks the required Java version needed and stops if it is above the available.
If you compile from the command line, there are switches to tell javac the source Java version and the target Java versions. I never had used them, so you better search for questions about them (i.e. javac source and target options). With those tools it will be the compiler that warns you against problems, without you having to explicitly check the version in your code.
There is a way to check the Java version, but you would need multiple executables to do it.
You would need a root executable, that would have a low-bar minimum Java version, simply so it can check the version of the systems, then it would launch an executable from there based on the system's Java version.
How you would come about this:
System.getProperty() allows you to, well, get system properties, along with a few other things, like versions of installed applications like Java.
You should create a separate JAR with one class:
public class Launcher {
public static void main(String[] args) {
String javaVersion = System.getProperty("java.version");
// Conditional to launch Jar file
if(correctVersion) { // if version is confirmed
Runtime.getRuntime().exec("java -jar whatever.jar");
}
}
}
The reason we need a root, lower bar executable, is because if the original executable can't run in the first place, how is it going to check the Java version?
Hope this works out for you. Sorry it took so long to get an answer.

Can not make GWT application work as Chrome packaged app, probably due to CSP

Keep getting CSP errors: "Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'"
The problem is probably due to HTML files generated by GWT which contain inline JS.
UPD: Changing to manifest version 1 helped, but this is a temporary workaroud, as Chrome 21 complains that it will no longer be supported.
UPD2: <add-linker name="xsiframe" /> does not help either
GWT 2.5.1 has finally fixed this problem. The release notes documenting this are here:
https://developers.google.com/web-toolkit/release-notes#Release_Notes_2_5_1
and they state that:
"Apps built with DirectInstallLinker should work in a page where inline scripts are forbidden (e.g. a Chrome extension)"
This means that it is now possible to use DirectInstallLinker to link your Chrome packaged app in a manner that satisfies the new security requirements of manifest version 2 regarding inline scripts. That is, by using DirectInstallLinker to link your app with GWT 2.5.1 selected as your GWT version, GWT will not place any script elements inline in its generated Javascript, and thus the new manifest version 2 requirement that there be no inline scripts will not be violated.
I have found that SingleScriptLinker also seems to work for my own app; however, Issue 7685 warns against using the SingleScriptLinker because "This generates a $doc.write line which is forbidden in packaged apps." I am using DirectInstallLinker myself.
Here is the Javadoc for DirectInstallLinker:
http://google-web-toolkit.googlecode.com/svn/javadoc/2.5/com/google/gwt/core/linker/DirectInstallLinker.html
To use this linker, you can include the following in your *.gwt.xml file:
<define-linker name="dil" class="com.google.gwt.core.linker.DirectInstallLinker"/>
<add-linker name="dil" />
(dil can be replaced by anything you choose, so long as there are no dashes or other illegal characters).
You will need to select GWT 2.5.1 as your version of GWT. If you're using an older version of GWT in an out-of-date version of Eclipse such as Ganymede (as I was), you'll have to upgrade to at least Helios and then import your project to your new Eclipse environment. The archive URLs for the Google Plugin for Eclipse that can be used for the latest three Eclipse versions can be found here:
https://developers.google.com/eclipse/docs/download
With the above in place, you should be able to set
"manifest_version": 2
in your manifest.json file and not experience any errors due to GWT-generated inline Javascript. This should allow your Chrome Web app to be acceptable to the Chrome Web Store (which now requires manifest version 2 for any new apps or for updates to present apps), so long as there are no other issues.
EDIT: new GWT bug reported: http://code.google.com/p/google-web-toolkit/issues/detail?id=7685, see also http://gwt-code-reviews.appspot.com/1838803/ which is related to this bug
In other words, it looks like, when fixed, you'll simply have to use the DirectInstallLinker (<add-linker name='direct_install'/>).
In the mean time, IIUC, you'd have to extend DirectInstallLinker and:
override getJsInstallLocation to return a copy a installLocaltionIframe.js without the $wnd part
override getModulePrefix to prepend var $wnd = $wnd || window.parent; to what's generated by super.getModulePrefix
I don't know CSP enough to give a complete answer, but the xsiframe linker is "customizable": create a class that extends com.google.gwt.core.linker.CrossSiteIframeLinker and overrides the appropriate methods, then use with a <define-linker> and <add-linker> in your *.gwt.xml.
For instance, getJsInstallLocation defaults to com/google/gwt/core/ext/linker/impl/installLocationIframe.js but there's a com/google/gwt/core/ext/linker/impl/installLocationMainWindows.js alternate implementation.
Similarly (and probably more importantly), getJsInstallScript defaults to com/google/gwt/core/ext/linker/impl/installScriptEarlyDownload.js but there's also a com/google/gwt/core/ext/linker/impl/installScriptDirect.js alternate implementation.
See http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java#204, http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/ and http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/core/Core.gwt.xml
Thanks to Thomas Broyer's advice. I created this GWT Linker. Now my GWT application runs perfectly as an Chrome Application (Tested on Chrome 32 and GWT 2.5.1).
public class CSPCompatibleLinker extends DirectInstallLinker {
#Override
protected String getJsInstallLocation(LinkerContext context) {
return "com/google/gwt/core/ext/linker/impl/installLocationMainWindow.js";
}
}
Dont forget to declare the Linker into your*.gwt.xml file:
<define-linker name="csp" class="com.sfeir.linker.CSPCompatibleLinker"/>
<add-linker name="csp" />
Manifest version 2 does not allow inline scripts. You need to make sure all scripts are linked instead and no JavaScript in HTML elements.

Overriding acm.program init() method; does Java have to be this hard?

Java problems
I am a student of Java. I managed to write about 15 Java programs so far and get them working on the PC. But I have not yet written a init() method like my latest assignment requires in order to initialize some instance variables. The compiler tells me that my init() method is attempting to override the final init() method in the acm.program. Isn’t that what an init() method is supposed to do? After exhausting all avenues on PC for the last week, I thought maybe it is an Eclipse problem on the PC. All the example code in the Java documentation shows little Mac windows. So I thought I would try moving my code to a Mac running Lion OS 10.7.2.
Switching to MAC environment.
The Mac claims to have Java installed but I think it’s just the run time environment, not a development environment. All I could find for applications is the Java VisualVM, which I assume is the virtual machine so there is no java development software. So… I downloaded Eclipse for Mac from Stanford’s website and got Eclipse IDE for Java Developers Version: Helios Service Release 2 and tried to run a simple program which included an import statement.
The import acm.program.*; statement is giving the compiler a problem: "acm cannot be resolved”. After researching this I think the problem is I have not downloaded the acm.jar archive and added that to my build path. Why this isn’t already done for me, as part of Eclipse I have no clue. I guess everything has to be difficult.
So I downloaded the acm.jar archive and it’s sitting in my download folder. I tried double clicking it and thankfully the mac won’t execute it. I tried dragging it into my source folder in Eclipse and then adding it to the build path. Once in the build path, Eclipse tells me the jar is missing. So I removed it from the build path and instead from inside Eclipse went to Properties/Java Build Path/Libraries/add External JARS… and navigated to my downloads folder where the acm.jar folder is to select the JAR. However, Eclipse seems to be looking for a .jar;.zip file, which there are none because my Mac helpfully already unzipped the folder. So I changed the open window to look for all files (.) and now I see individual .java files that are too numerous to add to the build path individually.
So back to the PC and download the acm.jar zip file and copy it over to the Mac in unzipped form and again add it to the build path as a zip file. This resolved the compiler error and my simple program executed on the Mac!
Next I will try my program with the init() method to see if that now works. Nope. Same problem on the Mac. This init method causes the following error: Multiple markers at this line
overrides acm.program.Program.init
Cannot override the final method from
Program
public void init() {
canvas = new HangmanCanvas();
add(canvas);
}
Does it have to be this hard or am I missing something?
Generally Macs have the whole JDK installed. Eclipse is nice, though.
This "acm" package isn't installed because it's not any kind of standard thing; this is like asking why your refrigerator doesn't come with asparagus already in it.
That last dialog was the right one; you need the original jar file. Try again, right-click and "Save As..." the link to save the file from your browser.
See 3. I find it particularly funny that anybody would use a Windows computer to make up for shortcomings of a Mac; in reality the Mac is infinitely more flexible and more powerful.
If you got a message that complains you're trying to override a final method, then you are indeed trying to do something wrong; final actually means "You're not allowed to override this." Perhaps you didn't fully understand the instructions for the assignment.
It gets better, I promise. Just be sure to use each of these annoyances as a learning experience.
There is no reasons why Java for the Mac would be any better than Java for the PC. The language and tools should work the same ... assuming that you are using the same versions of the language and similar versions of the tools.
Your problem with init is nothing to do with PCs versus Macs. So don't waste your time switching platforms to try to fix it. You need to figure out what the
On the face of is, the compiler / IDE is telling you the truth. Java won't let you override a final method. In fact the whole point of declaring a method to be final is to prevent overloading.
However, this does not make sense. According to the documentation I found here, the acm.program.Program.init() method is designed to be overridden. So why won't it let you?
I suspect that the cause of your problems is that you've downloaded or been given a copy of the JAR file that someone has messed around with. Someone has changes the method to be final (for some reason best kown to themselves), compiled it and put it up for people to download. Google is not always your friend ...
So, what I suggest you do is review all of the handouts and the files that were provided to find either the copy of the JAR that is provided, or the instructions on WHERE to download it from. Then replace the copy of the JAR you are currently using with the recommended one.
Why this isn’t already done for me, as part of Eclipse I have no clue. I guess everything has to be difficult.
How is Eclipse supposed to know what this "acm" stuff is? Which version you require? Where to download it from?