I am working with the apache orc-core java api. I have noticed a couple of things and was wondering if there are options to control them
Does not overwrite files. The call to OrcFile.createWriter fails if the specified file already exists. Is there an option to get it to overwrite by default?
Generates .crc files. If I write to a file called test.orc the program also creates a file called .test.orc.crc. Is there an option to disable this?
I know I can work around both of these simply by deleting the relevant files in the code. Was just wondering if there was a "proper" way.
Related
I've been trying to make jar application that can read a csv file in the same directory as it. This is, however, proving difficult as my means for accessing the file currently is:
InputStream is = getClass().getClassLoader().getResourceAsStream(filename);
Which works for my program running in the IDE and for my tests but doesn't work when I run the program from the compiled jar file. I have no idea how to get it to work for both. I seriously can't understand this path stuff, it seems like there are a million ways to do it and only one of them work for only one specific scenario.
I've been trying to make jar application that can read a csv file in the same directory as it.
Ah, there's your problem. That just isn't a thing.
There are only 2 types of files:
Application Resources
These are read only, and are as much part of your app as your class files are. It is not in any way relevant to think about 'editing' them - that's not the kind of thing they are. It is reasonable to assume that if this resource is somehow missing, the app is as corrupt / misinstalled as it would be if class files are missing.
For this, you use .getResource and .getResourceAsStream. And note that getClass().getClassLoader() is wrong, you want MyClass.class.getResource and then add a slash if you want to go from root (because getClass() potentially breaks when you subclass, and going via classloader is [A] just typing for no reason, and [B] breaks in bootload scenarios. MyOwnClassName.class.getResource never breaks, so, always use that).
This asks java to look in the same place class files are and nowhere else. Your class files are inside the jar files, and not next to them, therefore, it won't find a text file that is sitting next to jar files.
it does not make sense that it does work during development: That means you shoved a file inside the resources folder, which is equivalent to having a CSV file inside the jar file. You must have gone out of your way to tell your build system to do weird things. Don't do that.
If that CSV file is not intended to be user editable it should be inside the jar file and not next to it: That makes it an application resource. Examples of application resources:
You have a GUI, and you need to store the icon files and splash screen art and such someplace.
You ship static data with your app, such as a table of all US states along with the zipcodes they use (could be a text or csv file for example).
Templates of config files. Not config files themselves.
DLLs and the like that you need to unpack (because windows/linux/mac isn't going to look inside jars for them).
You're a webapp and you want to ship the HTML static files along with your webapp.
If this is what your CSV file is, the fix is to put it in the jar, not next to it, then load it with MyClass.class.getResource(name).
Config files and project files
For example:
For a rich text editor (like, say, LibreOffice Writer), the .odt files representing your writings.
Save games for a game.
A config file, which can be edited by the user, or is edited by your own app in a 'preferences' dialog. This stores for example whether to open the app full screen or not, or authentication info for a third party API you're using.
These should not be in the jar, should not be loaded with .getResource at all, and should not be in src/main/resources in the first place.
They also should not be next to your jar! That's an outdated and insecure model (the idea that editable files sit in the same place the app itself sits): A proper OS configuration means that an app cannot write to itself which is most easily accomplished by having it be incapable of writing to its directory. Some OSes (notably, windows) did this wrong for a while.
For example on windows, your app lives in C:\Program Files\MakorisAwesomeApp\makori.jar, and the data files for it live somewhere in C:\Users\UserThatInstalledIt\Documents\MakorisAwesomeApp.
oh linux, your app might be /usr/bin/makori and the data lives somewhere in the home dir. Config data might live in /etc/.
You don't "ship" your config files, you instead make installers that create them. You can do this part in-app by detecting that the relevant config file does not exist, load in a template (that is a resource, shipped inside your jar, loaded with getResource), and write it out, and tell the user to go look at it and edit it.
I really want a CSV file next to my jars!
Well, that's wrong, so, there are no libraries that make this easy. When you want to do silly things its good that APIs don't make that easy, right?
There are really hacky ways to do this. You can use .getResource to get a URL and then 'parse' this. This breaks the classloader abstraction concept (because in java, you can write your own classloaders and they can load from anywhere, not just files or entries in jars), but you can ask for 'yourself' (MyClass.class.getResource("MyClass.class")), pull the URL apart and figure out what's happening - does it start with file://? Then it is a file, so turn it into a j.i.File object, and go from there. Does it start with jar://? find the !, substring out the jar part, and now you know the jar. Make that a java.io.File, ask for the parent dir, and look there for the CSV.
You have to write all this. It's complicated code that is hard to test. You should not do this.
I have an app that accesses words from a csv text files. Since they usually do not change I have them placed inside a .jar file and read them using .getResourceAsStream call. I really like this approach since I do not have to place a bunch of files onto a user's computer - I just have one .jar file.
The problem is that I wanted to allow "admin" to add or delete the words within the application and then send the new version of the app to other users. This would happen very rarely (99.9% only read operations and 0.1% write). However, I found out that it is not possible to write to text files inside the .jar file. Is there any solution that would be appropriate for what I want and if so please explain it in detail as I'm still new to Java.
It is not possible because You can't change any content of a jar which is currently used by a JVM.
Better Choose alternate solution like keeping your jar file and text file within the same folder
Every few days, I get a SocketException, too many files open. I tracked the issue to a temporary pdf file that is being used during a certain process. The process passes a name of a temporary file that the library creates. At some point, the library opens an input stream but doesn't close it. Given that my code only has the name of the file, is there any way for me to close the stream?
Details:
Java Web App running in Tomcat6
The best approach is to request a version of this library with this bug fixed.
If this is not possible, get the sources, fix the bug yourself.
If you can't (only a binary jar file), try a tool like jd-gui, decompile the faulty class, fix, recompile that class and replace the .class in the jar.
If it still does not work use ASM and add a close statement at the right place. THIS SOLUTION SHOULD BE AVOIDED. It's complex if you do not master this technology.
I am creating a plugin for Eclipse, which contains tools for creating a custom type of project. These projects have a custom nature and builder. My builder (implements IncrementalProjectBuilder) takes a single input file, and generates a few (usually between 3 and 5) output files. When I run Clean Project, I need to remove the files the builder has previously generated.
Problem 1: The names of the generated files are not known exactly, but I do know the sort of files I expect to find (e.g. I know the extensions, and partial file names).
Problem 2: The user may add their own files to the project, which should not be affected by my build / clean steps.
My initial attempt was naive: remove every file except from the input file. This works, but has obvious problems.
My second attempt was better: I came up with a list of possible file names that may be generated, see if any of them exist and remove them.
By only knowing partial file names and matching them, I may inadvertently delete a user's file. E.g. I know I will generate a file called *_file.py. If the file I generate is called abc_file.py and the user has added their own xyz_file.py, I want to clean (remove) abc_file.py but leave xyz_file.py untouched.
The program which generates the output files from the input is constantly changing, and I don't want to rely on a concrete list of files that would need constant maintenance.
So, my question comes down to this. What methods exist for identifying the files generated by my custom builder, so I can remove them during a clean?
I've spent a couple of days Googling this one with not much to show for it. I am vaguely aware of a file system watcher in Java (Java7 WatchService?), but I don't know if that's the best solution to this problem.
Any information, advice or ideas appreciated.
One brute force approach would be to compare the project before and after the other program is invoked to get the list of files that were created/generated. Of course, it would be ideal if that program could somehow tell you which files it created. Once you have that list, you could iterate over those files as IFile's as use the setDerived() method to mark them as not being source files. When it comes time to clean the directory, you could use the derived setting to decide which files can be deleted.
I am developing a Java Desktop Application. This app needs a configuration to be started. For this, I want to supply a defaultConfig.properties or defaultConfig.xml file with the application so that If user doesn't select any configuration, then the application will start with the help of defaultConfig file.
But I am afraid of my application crash if the user accidentally edit the defaultConfig file. So Is there any mechanism through which I can check before the start of the application that whether the config file has changed or not.
How other applications (out in the market) deal with this type of situation in which their application depends on a configuration file?
If the user edited the config file accidentally or intentionally, then the application won't run in future unless he re-installs the application.
I agree with David in that using a MD5 hash is a good and simple way to accomplish what you want.
Basically you would use the MD5 hashing code provided by the JDK (or somewhere else) to generate a hash-code based on the default data in Config.xml, and save that hash-code to a file (or hardcode it into the function that does the checking). Then each time your application starts load the hash-code that you saved to the file, and then load the Config.xml file and again generate a hash-code from it, compare the saved hash-code to the one generated from the loaded config file, if they are the same then the data has not changed, if they are different, then the data has been modified.
However as others are suggesting if the file should not be editable by the user then you should consider storing the configuration in a manner that the user can not easily edit. The easiest thing I can think of would be to wrap the Output Stream that you are using to write the Config.xml file in a GZIP Output Stream. Not only will this make it difficult for the user to edit the configuration file, but it will also cause the Config.xml file to take up less space.
I am not at all sure that this is a good approach but if you want to go ahead with this you can compute a hash of the configuration file (say md5) and recompute and compare every time the app starts.
Come to think of it, if the user is forbidden to edit a file why expose it? Stick it in a jar file for example, far away from the user's eyes.
If the default configuration is not supposed to be edited, perhaps you don't really want to store it in a file in the first place? Could you not store the default values of the configuration in the code directly?
Remove write permissions for the file. This way the user gets a warning before trying to change the file.
Add a hash or checksum and verify this before loading file
For added security, you can replace the simple hash with a cryptographic signature.
From I have found online so far there seems to be different approaches code wise. none appear to be a 100 hundred percent fix, ex:
The DirectoryWatcher implements
AbstractResourceWatcher to monitor a
specified directory.
Code found here twit88.com develop-a-java-file-watcher
one problem encountered was If I copy
a large file from a remote network
source to the local directory being
monitored, that file will still show
up in the directory listing, but
before the network copy has completed.
If I try to do almost anything non
trivial to the file at that moment
like move it to another directory or
open it for writing, an exception will
be thrown because really the file is
not yet completely there and the OS
still has a write lock on it.
found on the same site, further below.
How the program works It accepts a ResourceListener class, which is FileListener. If a change is detected in the program a onAdd, onChange, or onDelete event will be thrown and passing the file to.
will keep searching for more solutions.