Getting resources from jars in an Applet's cache - java

I'm shoehorning an existing application into an Applet so we can say we support Web 2.0. Don't ask.
File system accesses are sprinkled all over our baseline so I'm in the process of converting them all to classpath based resource loading which is going swimmingly, except for the dozens of cases where we're traversing the directory system compiling lists of things. One simple example is looking inside a particular directory for .obj files and presenting that list to the user.
So I wrote an abstraction layer over files and directories in jars vs the file system, and it works just fine. My problem is that when I get the resource URL from class.getResource it contains the address for the jar on the server, but I know that the Applet has already accessed that jar for various classes.
I'm hoping there's a way to avoid getting the jar file from the server; e.g. the file is already cached somewhere and there's an easy way of obtaining it.

What you are seeing is deceptive. It is no business of applet and JWS apps. to know the location of cached resources. For that reason even if the resources is cached locally, the plug-in will claim the path is to the server.

Related

Resource Handling approach in Maven

I am handling below way to work with files.
1st Approach:
I am keeping my files in D:\Projects\JavaProjects\LearnCucumber\src\test\resources\
-With the help of ClassLoader, I am getting the path and working on files
ResourceUtils.class.getClassLoader().getResource(".").getPath();
2nd Approach:
Now, I keep file in D:\Projects\JavaProjects\LearnCucumber\BrowserDrivers\
using System.getProperty("user.dir") I am dealing with files in this approach.
Now Which approach is efficient, when we run our code in different platform(windows,linux) in terms of handling files. Does it really makes difference?
Try to avoid working with files on the filesystem as those are usually less portable from one operating system to the next one. Also if you put files at certain locations other users of your software need to have those files available at the same location as well, whereas with your approach #1 you can ship these files directly with your application (packaged as jar) and access it from the classpath easily.

JavaWebStart- multiple jars in same jnlp?

I'm trying to convert my java software jar into a Java WebStart application. I've managed to successfully deploy it as a WebStart with a jnlp file that provides details about the software's jar.
However, my software requires certain details to be stored locally in a file on user's machine. These details can be set & the file can be generated by having the user run another java software (a very small java utility software) coded by me. I wonder if it's possible to package in this smaller software's jar as well along with the main software using the tag. As far as I know, we can use the tag to specify additional jars/ libraries that our software jar uses.
Can we package in another java jar created by us in the jnlp and would it then get downloaded alongside the main software jar and other libraries (jars) when the user launches the jnlp ?
Kindly let me know. Thanks.
P.S: I know that all jars downloaded by a WebStart application end up in the deployment cache. Is there no way to specify where they should get downloaded to ? In my case, I would prefer it if the 2nd software's jar gets downloaded in an easier-to-find location.
Yes, it would be downloaded - but it would end up in the deployment-cache with no easy way to find it (names get all mixed up) or start it.
There's no way around webstart keeping the files in the deployment-cache: if you could specify the download-location different versions of jar-files with the same names and different codebase could end up in the same location causing no end of trouble.
I see two ways to get the wanted functionality:
Add the ability to change the local configuration as an additional function in the main application. You probably can use most of the existing code but use a method-call instead of starting it as a separate application
Create a second jnlp-file to start the configuration-program. From what you write it should be pretty small and not too much effort to create.

Java EE Application Directory Best Practice Question

I am relatively new at Java EE and have just gotten familiar with the traditional application directory structure (which includes the BUILD, DIST, NBPROJECT, SRC, and WEB folders). I was wondering: if my application requires to use some resources/assets (such as images or pdfs) on the server, in which of the 5 folders listed above should I place those resources? I think I can technically place them anywhere, as long as I reference the files correctly, but not sure what the common best practice is for this.
You would usually include static content e.g. images or PDFs which need to be read by http requests in WebContent e.g. if my-web is your WAR project:
my-web/WebContent/images
my-web/WebContent/scripts
my-web/WebContent/misc
This means you can access using for example:
/my-web/images/bob.jpg
/my-web/scripts/bob.js
/my-web/misc/bob.pdf
Storing the files here allows public access. I will quote this from the Eclipse help pages:
The Web content folder represents the
contents of the WAR file that will be
deployed to the server. Any files not
under the Web content folder are
considered development-time resources
(for example, .java files, .sql files,
and .mif files), and are not deployed
when the project is unit tested or
published.
You need to think about how the assets get delivered to the client before deciding where to put them. Resources such as ccs and static html pages are retrieved by the client using separate HTTP calls, so they need to be in a place that is accessible. In your case, I'd say they have to be at the level of index.jsp, or in subdirectories at that level. If you put them in WEB-INF, they will be inacessible from the outside world. You could possibly put them in META-INF but it would be an unusual use of that directory.

Creating java executable using JNI?

I am trying to create executable under windows platform for Java program using JNI ,C/C++ and invocation API, I have already created jar file for my program which includes all dependencies. I want to embed it in exe file, I was successful in running simple main class(present in file system) using JNI invocation API, I am planning to add jar file as resource in C/C++ program. But I don't know how do I run that jar file , One option is create temporary jar file on file system and run it using java, But I do not want to expose my jar file to everyone for security reasons, How can I run jar file on the fly using JNI ?
Compiling Java to an executable with GCJ does not work all the time, there are limitations as far as using reflection and other items such as UI classes, Look at this page.
If you convert you Java Code to a library or simply another module then you could link to it and simply run it without the need for a JVM.
My initial reaction was that I would be shocked if you could get this to work and have it be performant. But then I started thinking about it, and maybe you could pull this off using a custom class loader. If you embed the jar in the exe as a resource, it would be exactly the same as having the jar bytes be present at a particular offset in any file (whether an exe or not).
So, here's a potential strategy: implement a custom class loader that accepts the exe path and offset of the jar resource in that file. This would use a custom version of ZipFile that uses a fixed index offset for it's reads (unfortunately, it isn't going to be possible to use ZipFile itself - but if you grab the source of ZipFile it should be pretty obvious where you'll need to add the offset).
There is a bootstrapping issue here (how do you load the custom class loader?) - but I think it might be possible to do that from the JNI side. Basically you'd store the .class file for the loader as a separate resource in the exe, load it fully into memory then construct it using JNI calls. That will be a hassle, but it's just for one class, and then you can let the Java runtime take over the rest.
Sounds like an interesting project (Although, as others are pointing out, there isn't much security in what you are doing... I suppose that you could encrypt the embedded jar and add decryption code to the classloader, but you've kinda got to decide how far you want to take this thing).

Using the ClassLoader method to retrieve all resources under classes as Input Streams

My problem is one that you would think is quite common, but I haven't so far managed to find a solution.
Building a Java web app under Tomcat 5.5 (although a requirement is that it can be deployed anywhere, like under a WebLogic environment, hence the loading resources as streams requirement). Good practice dictates that resource files are placed under WEB-INF/classes and loaded using the ClassLoader's getResourceAsStream() method. All well and good when you know the name of the resource you want to load.
My problem is that I need to load everything (including recursively in non-empty sub-directories) that lives in a subdirectory of classes.
So, for example, if I have the following under WEB-INF/classes:
folderX/folderY
folderX/folderY/fileA.properties
folderX/fileB.properties
I need the fileA.properties and fileB.properties classes to be loaded, without actually knowing their names before the application is started (ie I need the ability to arbitrarily load resources from any directory under WEB-INF/classes).
What is the most elegant way to do this? What object could I interrogate to find the information I need (the resource paths to each of the required resources)? A non-servlet specific solution would be best (keeping it all within the class loading framework if possible).
Thanks in advance!
As far as I am aware, there is no such ability, since the classloader only attempts to load things it is asked for. It doesn't pre-fetch all items on the classpath, or treat them as a directory structure.
The way I would solve the problem is create a directory listing in a text file of all relevant resources at build time and include that in the war, and then walk it through that way.
You can do that with some tricks :)
Get the resource as URL, extract the protocol :
file protocol - get the URL path and you have a folder, scan for files.
jar/zip protocol - extract the jar/zip path and use JarFile to browse the files and extract everything under your path/package.

Categories