4

Once and for all somebody, explain how to correctly access resources like DATABASE, HTML files and so on.

Suppose my Maven JavaFX project looks something like this (check the image).

http://s30.postimg.org/lacoynzv5/image.png

It has it's

src/main/java

and

src/main/resources

in the Build Path

Build path

Inside resources I have a folder with a database and a folder with a html file.

Here is how I access the database and it works when I run it inside the IDE, but doesn't work after packaging or running the .exe file after mvn native

Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:src/main/resources/DB/SeeYourUse.sqlite");

Here is how I access my HTML file to use it in a WebView

String url = Main.class.getResource("/HTML/help.html").toExternalForm();  
webEngine.load(url);

And it DOES work inside the IDE (jfx:run and running as java application as well), but not a chance to run it after the deployment.

Here is the error I get when I run it and log it.

java.sql.SQLException: path to 'src/main/resources/DB/SeeYourUse.sqlite': 'E:\Programming\Java\Work\SeeYourUse\target\jfx\native\SeeYourUse-0.0.1-SNAPSHOT\app\src' does not exist

The QUESTION is: How do I properly load the database and the HTML to be able to use it at maximum?

Denis Rozimovschii
  • 428
  • 1
  • 6
  • 19

1 Answers1

2

src/main/resources is copied into your jar file directly, as is target/classes. You are able to access resources by class.getResource(String name) that returns the URL of a resource, and also Class.getResourceAsStream(String name) that will open a stream. But, in your specific case of a database, I would NOT put resources in a jar file as a jdbc driver loads database files directly from filesystem. You should extract a database to an external location by opening a stream to it and writing it to an external directory, at least if it does not exist already.

As for html files, you can retrieve URL's in case of such static resources and use them directly as noted above. Note however that the web engine will be unable to use other resources referenced from a html file, unless you can replace the logic that it uses to find them. In a case of such things, I would even extract the html file and all files it depends on into a temp location.

Michał Zegan
  • 456
  • 4
  • 12
  • 1
    What I said applies in case of a flat directory structure too, not necessarily packed into a jar file. – Michał Zegan Mar 08 '16 at 10:44
  • So do you mean I don't need to put resources inside the build path? Or just to keep the database somewhere outside (which, by the way, works, but doesn't seem like a good decision). – Denis Rozimovschii Mar 08 '16 at 10:45
  • 1
    After deployment, it is normal that your resources are in the same directory as your classes. this is usually packed into a jar file isn't it? – Michał Zegan Mar 08 '16 at 10:53
  • Well, after using the command jfx:native, maven gives me two folders. /app and /native. I used to run the application as .exe. I definitely need some tutorials or documentation on this. Do you have some useful links? – Denis Rozimovschii Mar 08 '16 at 10:58
  • 1
    Unfortunately not, but you can try reading about javapackager. still, I believe your resources *will* be packed like I said. I guarantee that your current app won't work as java application if you move it's jar file somewhere outside of the maven project structure. but html should load properly, and you didn't complain about html not loading, did you? – Michał Zegan Mar 08 '16 at 11:00
  • I reused the command jfx:native but my database is (jdbc:sqlite:SeeYourUse.sqlite) in the main directory. I moved the whole directory containing folders /app, /runtime and the .exe to the other place and as expected, it started and the things related to the database work properly, but the window containing the webview doesn't open, meaning it has an error. EVEN THOUGH I run it with getResource – Denis Rozimovschii Mar 08 '16 at 11:09
  • /lib with a lot of libraries, my database, SeeYourUse-1.0.0.cfg, SeeYourUse-1.0.0-jfx.jar. – Denis Rozimovschii Mar 08 '16 at 11:13
  • resources should be loaded from the jar file, check if the jar file contains resources too – Michał Zegan Mar 08 '16 at 11:14
  • The jar file contains all the compiled classes and all the resources, as expected – Denis Rozimovschii Mar 08 '16 at 11:15
  • so: the html file should actually load (path like html/whatever), database will not load as sqlite reads from folders, not from Class.getResource/etc, so I would extract the database and then use it. – Michał Zegan Mar 08 '16 at 11:17
  • What do you mean under "I would extract and then use it". What certainly should I do? – Denis Rozimovschii Mar 08 '16 at 11:18
  • 1
    Use `Class.getResourceAsStream()` to open the database file, and write it either to a tmp directory if your database is not to be modified, or to a permanent data directory for example .myprogramname in the user's home directory, if you intent to modify it. then you do not extract again if it exists. – Michał Zegan Mar 08 '16 at 11:20
  • Still getting null pointer exception when trying to access the html file. Maybe I'm not oppening it right? – Denis Rozimovschii Mar 08 '16 at 11:32
  • well, maybe remove the / from the beginning to the path to it? – Michał Zegan Mar 08 '16 at 11:33
  • If I remove it, It won't even work at IDE stage and the logger writes the same null pointer exception when I run the jar – Denis Rozimovschii Mar 08 '16 at 11:36
  • Suddenly, I changed "help.html" to "Help.html" and it worked :D But...without css though – Denis Rozimovschii Mar 08 '16 at 11:40
  • okay. if the path to the html file is good in relation to the root of the jar file, then getResource should work returning an URL. can the web engine load from an input stream or equivalent? I would prefer that approach if that is possible. You can also extract the html file to a temporary location. – Michał Zegan Mar 08 '16 at 11:42
  • I have edited/expanded the answer to make it easier to find what we were talking about. – Michał Zegan Mar 08 '16 at 12:04
  • Okay, the html now loads, but I have a problem with loading the css and images now – Denis Rozimovschii Mar 08 '16 at 12:16
  • Note the answer that I have modified. webengine probably does not load resources using Class.getResource family, so it has no chance of finding images/etc. Check if you can influence a way in which resources are loaded in web engine, if not, then you would have to extract all htmls, css and images to a common directory. – Michał Zegan Mar 08 '16 at 12:19
  • Extract using InputStream as well? – Denis Rozimovschii Mar 08 '16 at 12:26
  • Probably, but this still seems ugly doesn't it? first thing to do is to check if web engine can be told how to find resources. if not, then extracting like I said seems to be your only option – Michał Zegan Mar 08 '16 at 12:30
  • Ohh. I have read that javafx webengine supports jar urls. So it should actually work. – Michał Zegan Mar 08 '16 at 12:38
  • That is, loading of relative resources could work if you were loading from the URL as urls going inside jars are supported. – Michał Zegan Mar 08 '16 at 12:40
  • So how should I place inside the html a image? src="file:Images/example.jpg"? jar:HTML/Images/example.jpg? – Denis Rozimovschii Mar 08 '16 at 12:44
  • It probably should be a relative url like src="images/xxx" – Michał Zegan Mar 08 '16 at 12:44
  • This would work if I could somehow tell the webengine where my resources are, but how can I do it? – Denis Rozimovschii Mar 08 '16 at 12:54
  • 1
    It knows where the html was loaded from, so I actually believe it should also be able to resolve relative paths. If not, I am not a javafx developer and can't really help you further with this. – Michał Zegan Mar 08 '16 at 16:50