YA ClassNotFoundException involving the URLClassLoader - java

After looking through dozens of other SO questions involving these two classes, I've come to the conclusion that this might be a new one.
The code in question involves Eclipse (kepler), Maven, and GeoTools - specifically, a copy of ImageLab from their tutorial, which I've stripped down partially to play with the Style classes. I changed one bit of code to create an RGB style to replace the grayscale style the example uses - and suddenly I get a ClassNotFoundException on this snippet:
Layer rasterLayer = new GridReaderLayer(reader, rgbStyle);
If I put a breakpoint there and step into that constructor, I immediately get the CNFE on org.geotools.data.FeatureSource. This is a fairly frequently used class, though, in the gt-api jar, and it's already downloaded and sitting in my Maven Dependencies folder. In fact, I can even stick this in above that line:
FeatureSource<?,?> source = null;
...this compiles happily, and it still throws a CNFE on that constructor after it. It finds it, and then it can't find it??
That CNFE is being caught and eaten silently, apparently, if I just run the app without using debug mode - it later throws an NPE when it finds that Layer's style object is null.
I've tried restarting Eclipse, and running Project>Clean several times - same problem. gt-api.jar (specifically, gt-api-12-RC1.jar) is in the build path for that project. I can't step into the URLClassLoader, to see where it's looking; or at least, I don't know how.
Can anyone please explain this bizarre behavior, or better, suggest a solution? Alternately, can anyone tell me how I might get a better look at what the URLClassLoader is doing, or what it thinks its classpath is?

Related

JavaFX loading FXML causes warning and fails to load the file (skin/modena)

Situation
I'm trying to build a JavaFX App and for GUI I use SceneBuilder to produce fxml files for the different roots to use. Then I launch the App and at some point I'm trying to load some fxml file with new FXMLLoader(App.class.getResource("myFXML.fxml")).load() and set it as root on the scene on the stage.
Issue
99% of the times the loading has no problem at all and everything works as intended, but that 1% will fail and prevent the fxml loading without stopping the App but only throws the warning bellow.
WARNING: Caught 'java.lang.ClassCastException: class java.lang.String
cannot be cast to class javafx.scene.paint.Paint (java.lang.String is in
module java.base of loader 'bootstrap'; javafx.scene.paint.Paint is in
module javafx.graphics#18 of loader 'app')' while converting value for
'-fx-background-color' from rule '*.list-view' in stylesheet
jar:file:///C:/mysystem/.m2/repository/org/openjfx/javafx-controls/18/javafx-controls-18-win.jar!/com/sun/javafx/scene/control/skin/modena/modena.bss
The fxml that causes it most of the time is the one with a ComboBox in it but i don't think this has to do with it since it happened anywhere.
Important the warning is not consistent as well, at the pre-last line instead of *.list-view other times says *.button as well, but i am doing the same action to test it.
Reproducing the Issue
Reproducing is not consistent at all, the warning is descriptive and seems that the problem is on a JavaFX file (mentioned in the warning) and not in something I wrote. Thus I can't find a consistent way to reproduce it or handle the exception or something.
Tried so far
Removing the ComboBox (just in case)
Searched the internet to find nothing about it
Re-installing JDK did nothing
Note
I know there is much more information I can provide that may help but I'm exhausted right now. Maybe will add with edit later on.
Long Story Short
I was doing the FXML loading (new FXMLLoader(App.class.getResource("myFXML.fxml")).load()) and scene.setRoot(...) on another Thread and not the FX Thread. So make sure with Platform.isFxApplicationThread(); (as mentioned in the comments) that the operation happens on the FX Thread to ensure expected behavior.
Important
The answer is not complete, it is a placeholder for anyone searching it currently and this resolves the issue.
Improvements
I will try as soon as possible to update the question with more information and reproducible example. Also I will with the help of the comments continue the research to find solid explanation for the issue. In the mean time feel free for edits or post new better answers.

Why does the order in which Netbeans loads Java Libraries cause errors sometimes? and how do I avoid it?

Basic background data: Windows 7, Netbeans 8.0.2, LWJGL 2.9.3, Slick Util.
The rest of the code is my own.
So, periodically, I was having what I thought was a bug, that caused my program to run within the IDE, but would fail when I used "Clean and Build" on the project.
Today, when it happened again, I decided to get to the bottom of it. So, taking a copy of the whole project folder, that was working and otherwise identical, and replacing 1 file at a time, and testing it, I was able to narrow it down to the /nbproject/project.properties file.
Every other file could be replaced and the problem persisted. Replace ONLY this file, and the problem went away. So then I loaded up both files and compared them side by side (using the Netbeans "Diff to..." feature) and narrowed it down to the following lines:
javac.classpath=\
${libs.LWJGL-2.9.3.classpath}:\
${libs.0-Slick_Util.classpath}:\
${libs.0-Loaders_v03.classpath}:\
${libs.0-Text2D_v03.classpath}:\
${libs.0-Foundation_v04.classpath}:\
${libs.0-Abstracts_v04.classpath}
Now this code, looks like it is telling the compiler the ORDER in which the libraries should be loaded (I may be wrong).
With that in mind, I decided to test it. I copied this block from the working file, to the non-working file, and it worked just fine. The working code btw is this:
javac.classpath=\
${libs.LWJGL-2.9.3.classpath}:\
${libs.0-Slick_Util.classpath}:\
${libs.0-Foundation_v04.classpath}:\
${libs.0-Abstracts_v04.classpath}:\
${libs.0-Loaders_v03.classpath}:\
${libs.0-Text2D_v03.classpath}
The only differences, you may notice, is the ORDER. Continuing my test, I went into the non-working project's Library properties page, and simply re-ordered the libraries to match the working list. PROBLEM WENT AWAY! If I simply moved the Foundation and Abstracts libraries down in the list, the PROBLEM CAME BACK!
I must have tried a dozen different order combinations, and got about 2/3 that failed, and 1/3 that worked. The ones that worked all involved Foundation and/or Abstracts to be near the top.
Why is this happening? How can I know what order my libraries need to be loaded to avoid the error?
The error btw is this:
F:\Dropbox\2-Documents\4-Java Programming\Library\0-LoadingScreen_v04-Copy\src\A_Library\Test_LoadingScreen.java:94: error: cannot find symbol
Lib_Foundation .setConfigLocation(configLocation);
symbol: method setConfigLocation(String)
location: class Lib_Foundation
Any information that can help me avoid this problem in the future will be appreciated.
It would appear that either “Loaders_v03” or “Text2D_v03” contains its own version of Foundation, including an incompatible Lib_Foundation class. A classpath is searched in order, so your current solution—reordering javac.classpath—will always work, assuming NetBeans doesn’t mess with it the next time you make any change to your project.
Whether that will break Loaders and Text2D depends upon how well Foundation adheres to object-oriented design: public classes and their public members are never supposed to be changed or removed in successive versions. (That is why 20-year-old code written for Java 1.1 will still compile in Java 8.)

Annotation processor-generated Errors/warnings not showing in Eclipse editor or Problems view

I have written a customer annotation processor to generate various source files, wrapped in an Eclipse plugin. As part of this process it also logs various errors and warnings using the usual call ProcessingEnvironment#getMessager().printMesssage(Kind, String, Element).
I have been testing the processor by debugging the plugin in Eclipse. In the launched sub-instance of Eclipse the processor all works as expected - source files are generated, picked up and interpreted by the compiler as desired. Any compiler (i.e. non-custom) errors in the generated and non-generated appear in the editor, Problems view etc. as expected.
However I am seeing a lot of inconsistencies in terms of how custom errors and warnings appear. The behaviour I see is as follows:
If no Element is specified all messages appear in the Error Log under type Info, regardless of the Kind specified when logging the error.
If a message is of Kind NOTE it always appears in the Error Log under type Info, regardless of whether or not an Element is specified.
Otherwise, if an Element is specified errors and warnings intermittently appear in the Problems view and in the editor; sometimes they don't appear anywhere. They never appear in the Error Log, whether the Kind is ERROR or WARNING
As per the emphasis above, the real issue is item 3 - that under certain situations I simply cannot get errors to appear in the editor despite being logged on valid elements. In fact, I have managed to reliably make errors appear and not appear by simply changing the name of a particular generated source file.
Of course the issue is not the filename itself, but it is certainly the case that generating the class with a name that matches references already in code causes errors to get hidden, whilst generating it with a different name (or not at all) causes errors to show (as well as all the regular compiler errors caused by a missing class). The strangest thing is that there is nothing fundamentally different about this generated class compared to any of the others (of which there are many), although it is unique in its structure and how it is referenced. It also reasonably long (around 400 methods), but artificially shortening it did not make any difference. Other generated classes also have existing references in the code and don't suppress errors.
Unfortunately I have also not yet had the time to test if this issue occurs when the Eclipse plugin is deployed (i.e. running in a 'real' instance of Eclipse), or indeed if the issue occurs when calling javac explicitly or invoking a Maven build.
Without posting the full code of the plugin I don't expect anyone to be able to help directly, but I am very open to any suggestions or advice if anybody has experience issues with annotation processor-generated errors. It seems to me like a bug in Eclipse, but I have not been able to find any reference to it online. I also cannot find any errors in the .metadata/.log files of either the underlying Eclipse instance or the launched sub-instance of Eclipse. Finally I have ensured that there are no Exceptions suppressed or reported in the annotation processor code.
Eclipse version details:
Version: Luna Service Release 1a (4.4.1)
Build id: 20150109-0600
Any help appreciated and many thanks in advance :)
If a problem/error has to be shown in the Eclipse Problems view, you need to create a Marker on the particular resource (file/folder/project). Please see the following links on how to create the Markers in an Eclipse Plugin:
https://wiki.eclipse.org/FAQ_How_do_I_create_problem_markers_for_my_compiler%3F
https://www.eclipse.org/articles/Article-Mark%20My%20Words/mark-my-words.html
In terms of how the custom errors/warnings appear, the Problems view (or the generic MarkersView) is completely flexible to show/hide certain elements. Have a look at the "Configure Contents..." menu in the Problems view to get more idea.

How to find file path of a Java API class?

In particular - the Applet.class. How could I find where it locally resides? I have tried the following, but I get an exception:
System.out.println(JApplet.class.getProtectionDomain().getCodeSource().getLocation().getPath());
It is of course somewhere in Program Files/Java/jdk_7_xx/ but I have had quite a look around and searched online and cannot find the answer. I have always wondered where specific classes reside on the system.
Note: If you want some more detail (not necessary to read below this):
What I specifically want to do is edit the Applet.class and point my Eclipse to a new JRE System Library that contains the edited Applet.class. In theory this sounds plausible, yet in practice I am unsure.
This is needed so I can test legacy code which keeps making calls to super methods - I have tried many frameworks/approaches and tried multiple possible solutions that have been posted on stack overflow and other online resources - none work.
Found the JApplet.class in C:\Program Files (x86)\Java\jdk1.7.0_25\jre\lib\rt.jar
Made a back-up of jdk1.7.0.25 on my desktop and put it in a folder Desktop\BACKUP\jdk1.7.0.25
Unzipped it (rt.jar), decompiled Applet.class with jad, changed some methods and even added a new one, recompiled it, rezipped it, replaced the old rt.jar with the new one, made a new eclipse project and made it use the JRE in Desktop\BACKUP\jdk1.7.0.25 and it worked perfectly.
..do you know how I can find the specific path of the Applet.class?
For your own PC? Sure. For the PC of a client of your applet? No.
In fact, Oracle (or was it Sun?) eventually decided it was not the business of an app. launched within the Java Plug-In (e.g. applets or JWS apps), to know where the classes were cached. Not even it that app. was fully trusted.
I'm assuming its in a jar somewhere?
Don't assume. It is set in the Java Control Panel, which defaults to 'no compression'.

jMonkeyEngine: importing .x models

I found this importer for .x files in the jMonkeyEngine SDK plugins: http://jmonkeyengine.org/groups/contribution-depot-jme3/forum/topic/directx-to-j3o-converter/?topic_page=1&num=15 , and I downloaded/installed it successfully via the Tools -> Plugins menu.
But I'm not sure how to use it. I tried adding a model to my assets folder, then right-clicking it in the SDK and choosing "Convert to j3o Binary", but this accomplished nothing: no dialogs popped up, and nothing seemed to change at all. My code still generates a runtime warning stating that it doesn't know how to load a .x file.
P.S. I posted this question as a reply on the linked thread as well. So far, no responses, so that's why I'm posting here, but just a heads-up in case someone replies there in the near future.
Update: A user replied to the thread, suggesting I check to see if any errors are being thrown (a little red error icon in the bottom-right corner of the screen). Sure enough, there was, and the error message was the converter complaining about not being able to find the dwarf.jpg texture. So I moved the texture into the Models folder next to the dwarf1.x model.
However, the conversion process is still behaving the same way, except that the error icon doesn't come up. In other words, nothing appears to be happening now, and no error messages are being thrown. I don't see any .j3mo file having been created anywhere, and my code is still causing a runtime exception that complains about not having a loader for .x files. (Note: I saw the filename typo in my screenshot, "dwarf.x" instead of "dwarf1.x", and have since corrected it, so that is not related to the problem at all)
Ok, found out the problem. The converter was still not finding the texture, even though it had stopped reporting the error about it. I had to rename the texture to match the model's filename exactly (except for the extension, of course), so "dwarf.jpg" became "dwarf1.jpg". Note also that it has to be in the same exact folder: in my case, I put it in the project folder/assets/Models/

Categories