Can GCP cloud function access (write) to /src/main/resources? - java

I have a cloud function that triggers a jar, it start well until I try to write files in /src/main/resources, where I can read, in the moment that I try to write the program fails and throw an exception.
So can I write directly to /src/main/resources or I must to implement the Cloud Storage library?
References:
https://cloud.google.com/storage/docs/reference/libraries#client-libraries-install-java
https://cloud.google.com/appengine/docs/standard/java11/using-cloud-storage
How to read a file from maven resources folder in GCP Cloud Function?
Thanks to all.

No java code (regardless of platform) can write to that 'directory', in the sense that the point of that dir is that these files end up in the same place that your jar files end up, and that you read them using MyClass.class.getResource. If you ever write new File("src/...") you messed up ('src'? In production there is no 'src', obviously).
That abstraction (MyClass.class.getResource and friends) offer, intentionally, no way to write anything, because jar files are not meant to be writable.
The right place to store mutable data on disk is nowhere near your jar files; for end user systems, generally write in System.getProperty("user.home") and then from there a subdir, such as .yourapp, or ask the user which data directory is appropriate; different OSes have different 'flavours' (linux wants /var or ~, apple wants ~/Library/Application Support or /Library/Application Support, windows is all over the place but probably wants HOME/My Documents, etcetera), and the only one that is common amongst all of them is 'some subdir off of the user's home directory'.
For cloud in particular, you must implement the Cloud Storage Library; the actual underlying OS system your google cloud app runs on is epheremeral (it can just disappear on you and its resources are tossed into the void, if your app is written such that this is a bad thing, your app is broken).

Related

Check if I can remove file

I'm opening many types of files using external applications which are available on phone. For security reasons I need to delete this file when the external app does not need it. How can I check if I can safely remove file which are used by third app ?
First of all you need to know which files are used by the third app. You can simply do it by analyzing, (decompiling, if needed) the source code of the application. After knowing all the files used by the third party app you need to check if the third party app actually running or not, because the third party app might use some temporary files, which could be removed when it's no longer open.
If you just want to make a simple cleaner, which cleans the trash of all the apps, then you should simply just remove certain file types (like .tmp files) and remove the cache of the apps.
First of all, I think there is no 100% way to determine if file is not used by another application.
I you are asking about files in sandbox of other apps, by the way you be able to remove such files because they have granted permissions only for app that they are belong to. So you need root access in this case.
You can remove file like cache,tmp ... files like system app manager does. If third-party is built correctly this should not affect application.
Also another method is to determine how often file is being used is based on unix file timestamps, they are
Access - the last time the file was read
Modify - the last time the file was modified (content has been modified)
Change - the last time meta data of the file was changed (e.g. permissions)
You can check for example the date when app was installed, than check access time of the file and determine does the application require this file.
But again there is no 100% guarantee that you won't brake an app.

How to save application data for use across users in OS X

I have a Mac Java application that needs to persist data across reboots. The data needs to be saved so that any user has access to it. E.g. an SQLite database file that can be used for all users.
It looks like the /Library/Application Support/ folder is supposed to be used for this, but I'm not able to write to it without making my app run as root or changing the permissions of the file to rwxrwxrwx.
What is the proper way to save application-level data on Mac?
The developer documentation covering this is a bit of a large topic:
https://developer.apple.com/library/Mac/referencelibrary/GettingStarted/GS_DataManagement_MacOSX/_index.html#//apple_ref/doc/uid/TP40009046
https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40010672
According to the File System Programming guide you should make a specific subdirectory inside /Library/Application\ Support for your app to store app data common to all users on the system. I'd use reverse domain name notation such as com.yourcompany.yourapp or something else unlikely to collide with another app's use of the common directory for this.
You might also look into using an existing app bundler for OS X such as https://bitbucket.org/infinitekind/appbundler rather than hard code paths to file locations.

Where to typically save external data from Java application?

Ok, the question is quite simple.
I have a Java program, which I am extracting some save-files to an external location.
Right now, I use C:/ApplicationName, however, that is a very bad way to do that.
I know alot of locations i could use, for instance:
%Appdata%
C:\Program Files (x86)
C:\Users\Users\Documents (Ive seen some indie games use this.)
Other locations?
But I can't figure out, when to use the proper one.
And if i want to support Linux and OSX, is there a libary, which supports that, or do i manually have to wrap them into an if/else with System.getProperties("os.name")?
Keep in mind that sometimes when games save to a specific directory, they aren't built to be cross-platform.
There are two ways you could do this. The first (and personally my preferred version) is to save in the directory of the application. This also has the advantage of being portable. However, the saves are linked to the application, so if the user deletes the application and reinstalls later they'll lose their data (which may or may not be a good thing).
Another option is to use System.getProperty().
Specifically, you can use:
System.getProperty("user.dir");
System.getProperty("user.home");
System.getProperty("user.name");
To figure out where to put your files.
This will be a lot more complicated, so the first method is preferred.
If it's data the user does not need direct access to, such as stored application/game state data, then it's appropriate to store it in the user's application data directory. Try this:
1) Determine the OS.
2) Get the user home directory.
System.getProperty("user.home");
3) Append OS-specific application directory:
Mac: /Library/Application Support/MyApp
Windows: \\Application Data\\MyApp
Linux: MyApp (there's no convention here that I know of)
If the data needs to be exported, such as saving a document from your application, then ask the user where to store the file via a file dialog, defaulting to their Documents directory.

Change the appearance of cache files in Android

For my app I download some resources like images and small mp3 and save them in the external storage (at /mnt/sdcard/Android/data/com.example.packagename/cache for example.
But I don't want that if a user explores that folder finds all the resources in a "common format".
One of my options is to remove the extensions (I know it's easy to guess the file type even if it have not extension but is a basic protection against most users)
I have noticed most of the programs that have their caches at the external storage don't have their cache as raw files.
I wonder if is there any easy way (with some class or something) for "hiding" those files and access them transparently or I must implement my own system
(It is not vital that these files remain hidden but I'd like keep those resources "unknown" unless a user takes a special trouble to see them)
Thanks
You can use ObjectOutputStream, it will save data as binary data, when the user tries to open it, even using Text Editor, it will show corrupted data, and here some sample how to use it Writing objects to file with ObjectOutputStream

Java OutputStream equivalent to getClass().getClassLoader().getResourceAsStream()

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

Categories