I have this code on an applet. The applet works ok, but I get a lot of unnecessary duplicate download. In particular, I have noticed that each "getResource" triggers a download of the .JAR file.
static {
ac = new ImageIcon(MyClass.class.getResource("images/ac.png")).getImage();
dc = new ImageIcon(MyClass.class.getResource("images/dc.png")).getImage();
//...other images
}
How can this be avoided?
Simply removing all instances of URLConnection.setDefaultUseCaches(false) will solve the problem.
Please refer for more details.
http://java-junction.blogspot.com/2009/11/applet-jar-caching-not-working.html
Do you include the applet to a HTML page? If so, try to enable the JAR caching, as is described here: http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/applet_caching.html
If that does not help for some reason :) perhaps expose your resources / images along your applet JAR on a web server and reach them using separate HTTP requests (yes, its ugly and yes, it does not reduce number of needed downloads, but it at least reduces the amount of data that need to be transferred).
Only a workaround:
You could put your images in a zip file inside the jar, get that using a ZipInputStream and extract the images from there.
Which Java VM do you use? And which Server do you use?
There is a bug in the browser plugin on Linux.
If the server does not send the modified date then Java can not cache the jar file.
If your applet always downloads the jar even though jar is cached, make sure you have not disabled the URLConnection's caching via the API: URLConnection.setUseCaches and URLConnection.SetDefaultUseCaches.
ImageIcon's underlying mechanism for fetching the resource is a URLConnection. Calling URLConnection.setDefaultUseCaches(false), sets a "part of the static state of all URLConnections" which cause the JRE to ignore the cache and redownload the entire jar every time it accessed.
Simply removing all instances of setDefaultUseCaches will solve the problem.
this is a repost from: http://java-junction.blogspot.com/2009/11/applet-jar-caching-not-working.html
Related
I've developed a JSP that writes a PNG file in a folder of deployment directory. After writing the contents, flushing, closing and syncing the file I try to show it in the same JSP using a tag but most of the times the imatge doesn't appears in the renderized page on the browser (the request of return a 404 Not Found response). The file is created (I can see the file into the folder in the system explorer).
I'm using Tomcat 8 as web container and I'm executing the webapp and Tomcat in the Eclipse Luna IDE.
Can anyone help me?
I believe this has been answered before in a slightly different form:
Tomcat 7 returns "304 Not Modified" on modified/non existent resource
However, since you are probably only generating your PNG files once (or maybe not very often), you have IMO a valid use case.
Since Tomcat does do caching, I think that you might want to consider using cachingAllowed="false" on your <Context>. Note that you will likely observe a slight performance drop since Tomcat will be going to the disk for every static request instead of consulting its cache.
You also have the option of writing your own servlet to serve the auto-generated PNG files directly from the disk. It can be complicated to write your own static-resource servlet with all the bells and whistles that Tomcat's DefaultServlet supports, but you can skip a lot of that and just always serve the whole file regardless of what the clients requests.
How would you go about opening an .xml file that is within a .jar and edit it?
I know that you can do...
InputStream myStream = this.getClass().getResourceAsStream("xmlData.xml");
But how would you open the xmlData.xml, edit the file, and save it in the .jar? I would find this useful to know and don't want to edit a file outside of the .jar... and the application needs to stay running the entire time!
Thank you!
Jar files are just .zip files with different file suffix, and naming convention for contents. So use classes from under java.util.zip to read and/or write contents.
Modifying contents is not guaranteed (or even likely) to effect running system, as class loader may cache contents as it sees fit.
So it might be good to know more about what you are actually trying to achieve with this. Modifying contents of a jar on-the-fly sounds like complicated and error-prone approach...
If you app. has a GUI and you have access to a web site/server, JWS might be the answer. The JNLP API that is available to JWS apps. provides services such as the PersistenceService. Here is a small demo. of the PersistenceService.
The idea would be to check for the XML in the JWS persistence store. If it is not there, write it there, otherwise use the cached version. If it changes, write a new version to the store.
The demo. writes to the store at shut-down, and reads at start-up. But there is no reason it could not be called by a menu item, timer etc.
I am attempting to store the change made to my application's properties. The .properties file is located in resources package, which is different from the package that contains my UI and model.
I opened the package using:
this.getClass().getClassLoader().getResourceAsStream("resources/settings.properties")
Is there a functional equivalent of this that permits me to persist changes to the Properties Class in the same .Properties file?
In general, you cannot put stuff back into a resource you got from the classloader:
Class loader resources are often read-only; i.e. held in read-only files / read-only directories.
If you got the resource from a JAR file, JAR files are not simply updateable. (To "update" you need to extract the old JAR's contents and create a new JAR with the updated contents. It is all to do with the structure of ZIP files ...)
In some cases, the class loader resource will have been downloaded on-the-fly, and there is no way to push changes back to the place where you downloaded from.
Even if you can update a resource you got from the classloader, it is a bad idea / bad practice.
Doing this "pollutes" the clean application installation with a user's preferences. Among other things, this means that the installation cannot be shared with other users (unless you handle preferences for multiple users ...).
There are security issues with having applications installed as writeable so that embedded preferences can be updated. Think viruses! Think one user who might be inclined to trash another user's preferences!
There are administration issues with having user-specific copies of applications. And if the user has to install his own copy of an app, there are potential security issues with that as well.
There may be technical issues with file locking or caching on some platforms that either get in the way of (safe) updates or make it difficult for an application to load the updated resource without a restart.
Finally, this is NOT the way that system administrators (and educated users) expect software to behave. Java applications should deal with user preferences in the expected way:
You can use the Java Preferences API.
You can write a Properties file containing the preferences to an OS-appropriate user-writable directory.
On Windows, you could use a Windows-specific API to store the preferences in the Windows registry, except that this makes your application Windows dependent. (I can't see any real advantage in doing this, but I am not a Window expert.)
When you wrap your app up as a JAR file, your properties file will be one (possibly compressed) file within that JAR, and it would be a bad idea to try to write to your own JAR.
getResourceAsStream() is meant to open resources for reading, and these can be anywhere on the classpath. You can't write to URLs or inside JARs, you can only write to files, so it doesn't make sense to give you the same API for output.
Find yourself a directory you're allowed to write into, and write your properties there.
It may be a good idea to copy your properties from your installation classpath (possibly inside a JAR) directly out to a file if it doesn't yet exist, as a first operation upon application startup. This will give you a properties file you can write to, yet the master copy of this properties file will come from your project deliverable.
It sounds like you want to store user preferences. Consider using the Java Preferences API for that.
In addition to Carl's answer, if you're going to read and write to this file frequently, and expect that your application will expand in scope, consider whether to go one step (or several steps) further and use a file-based database like SQLite. There are a few JDBC wrappers for SQLite that would allow you to go beyond the basic string key-value lookup that the Java Properties interface provides.
even though writing the file into resources is not good practical, we still need to do it when our application only run in IDEA locally without deployment, then we can do it as below:
URL resource = Thread.currentThread().getContextClassLoader().getResource("settings.properties");
String path= resource.getPath();
OutputStream outputStream = new FileOutputStream(path);
//outputStream write
I have been using tomcat for sometime and still can't find a good way to do file upload. Just wonder how you guys handle file upload.
You know how you can create a symlink in the application to another fs. but then by default tomcat removes your symlink and everything within the symlink. so this add extra steps to auto deployment. I know there are patch that you can change the behavior. but that will make add extra steps to tomcat upgrade, and patch might not be available always.
I use fckeditor(with it's servlet connectors), spring, struts 1/2 and sometime just plain servlet for the fileupload.
What is the best way to do this?
Another requirement is, uploaded file should be viewable and in a nice location so that backup script can backup easily, ideally not within the apps (or just a symlink within the apps)
Any comment is welcome!
=)
Personally, I place the files in a location relative to $CATALINA_BASE:
File dir = new File(System.getProperty("catalina.base"), "uploads");
I need some ideas on how I can best solve this problem.
I have a JBoss Seam application running on JBoss 4.3.3
What a small portion of this application does is generate an html and a pdf document based on an Open Office template.
The files that are generated I put inside /tmp/ on the filesystem.
I have tried with System.getProperties("tmp.dir") and some other options, and they always return $JBOSS_HOME/bin
I would like to choose the path $JBOSS_HOME/$DEPLOY/myEAR.ear/myWAR.war/WhateverLocationHere/
However, I don't know how I can programatically choose path without giving an absolute path, or setting $JBOSS_HOME and $DEPLOY.
Anybody know how I can do this?
The second question;
I want to easily preview these generated files. Either through JavaScript, or whatever is the easiest way. However, JavaScript cannot access the filesystem on the server, so I cannot open the file through JavaScript.
Any easy solutions out there?
Not sure how you are generating your PDFs, but if possible, skip the disk IO all together, stash the PDF content in a byte[] and flush it out to the user in a servlet setting the mime type to application/pdf* that responds to a URL which is specified by a link in your client or dynamically set in a <div> by javascript. You're probably taking the memory hit anyways, and in addition to skipping the IO, you don't have to worry about deleting the tmp files when you're done with the preview.
*****I think this is right. Need to look it up.
Not sure I have a complete grasp of what you are trying to achieve, but I'll give it a try anyway:
My assumption is that your final goal is to make some files (PDF, HTML) available to end users via a web application.
In that case, why not have Apache serve those file to the end users, so you only need your JBOSS application to know the path of a directory that is mapped to an Apache virtual host.
So basically, create a file and save it as /var/www/html/myappfiles/tempfile.pdf (the folder your application knows), and then provide http://mydomain.com/myappfiles (an Apache virtual host) to your users. The rest will be done by the web server.
You will have to set an environment variable or system property to let your application know where your folder resides (/var/www/html/myappfiles/ in this example).
Hopefully I was not way off :)
I agree with Peter (yo Pete!). Put the directory outside of your WAR and setup an environment variable pointing to this. Have a read of this post by Jacob Orshalick about how to configure environment variables in Seam :
As for previewing PDFs, have a look at how Google Docs handles previewing PDFs - it displays them as an image. To do this with Java check out the Sun PDF Renderer.
I'm not sure if this works in JBoss, given that you want a path inside a WAR archive, but you could try using ServletContext.getRealPath(String).
However, I personally would not want generated files to be inside my deployed application; instead I would configure an external data directory somewhere like $JBOSS_HOME/server/default/data/myapp
First, most platforms use java.io.tmpdir to set a temporary directory. Some servlet containers redefine this property to be something underneath their tree. Why do you care where the file gets written?
Second, I agree with Nicholas: After generating the PDF on the server side, you can generate a URL that, when clicked, sends the file to the browser. If you use MIME type application/pdf, the browser should do the right thing with it.