Get resource URL from project specific path
You would use one of the bundle resourse URL methods
[[NSBundle mainBundle] URLForResource:@"acknowledge1"
withExtension:@"wav"
subdirectory:@"snd/archer"];
NSBundle.mainBundle().URLForResource("acknowledge1", withExtension:"wav" subdirectory:"snd/archer")
In latest Swift:
Bundle.main.url(forResource: "acknowledge1", withExtension:"wav")
Get Resource URL Path in Java Spring
The answer ended up being something really stupid on my part! In the firebase console there are 2 JSON files you can download.
google-services.json
is for the clientservice-account-credentials.json
is for the server admin SDK (the one I should have been using)
Don't mix the two up!
Get all URLs for resources in sub-directory in Swift
Consider that the yellow folders are virtual groups, not real folders (although Xcode creates real folders in the project directory). All files in the yellow folders are moved into the Resources
directory in the bundle when the app is built.
Real folders in the bundle are in the project navigator.
How to get absolute path to file in /resources folder of your project
You can use ClassLoader.getResource
method to get the correct resource.
URL res = getClass().getClassLoader().getResource("abc.txt");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();
OR
Although this may not work all the time, a simpler solution -
You can create a File
object and use getAbsolutePath
method:
File file = new File("resources/abc.txt");
String absolutePath = file.getAbsolutePath();
Is there an analogue to getResources, but using a path outside the project defined as an environment variable?
Do not call the getPath() method of URL. It does not return a valid file name. If the returned resource URL points to a file path containing characters that aren’t allowed in URLs, like spaces, they would be percent-escaped.
Regardless, while you could theoretically create your own URLClassLoader in order to call getResource, there is no point to doing so. getResource and getResourceAsStream are specifically intended to read data bundled with an application.
I don’t see anything wrong with your use of Paths.get
as it is.
I am concerned that the structure of the TEST_DATA directory will change and break my code. Is that something I should worry about?
Yes, but using getResource will not change that. getResource would actually be worse, because it would just return null if the desired resource is not found. When you read from a Path, you will get an informative exception (like NoSuchFileException) instead of just a mysterious null.
For what it’s worth, Java recommends using system properties instead of environment variables for configuring an application. System properties have to be set explicitly, and won’t just be something “left over” in a user’s login initialization that they forgot about. From the documentation of System.getenv:
System properties and environment variables are both conceptually mappings between names and values. Both mechanisms can be used to pass user-defined information to a Java process. Environment variables have a more global effect, because they are visible to all descendants of the process which defines them, not just the immediate Java subprocess. They can have subtly different semantics, such as case insensitivity, on different operating systems. For these reasons, environment variables are more likely to have unintended side effects. It is best to use system properties where possible. Environment variables should be used when a global effect is desired, or when an external system interface requires an environment variable (such as PATH).
URL to load resources from the classpath in Java
Intro and basic Implementation
First up, you're going to need at least a URLStreamHandler. This will actually open the connection to a given URL. Notice that this is simply called Handler
; this allows you to specify java -Djava.protocol.handler.pkgs=org.my.protocols
and it will automatically be picked up, using the "simple" package name as the supported protocol (in this case "classpath").
Usage
new URL("classpath:org/my/package/resource.extension").openConnection();
Code
package org.my.protocols.classpath;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
/** A {@link URLStreamHandler} that handles resources on the classpath. */
public class Handler extends URLStreamHandler {
/** The classloader to find resources from. */
private final ClassLoader classLoader;
public Handler() {
this.classLoader = getClass().getClassLoader();
}
public Handler(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
protected URLConnection openConnection(URL u) throws IOException {
final URL resourceUrl = classLoader.getResource(u.getPath());
return resourceUrl.openConnection();
}
}
Launch issues
If you're anything like me, you don't want to rely on a property being set in the launch to get you somewhere (in my case, I like to keep my options open like Java WebStart - which is why I need all this).Workarounds/Enhancements
Manual code Handler specification
If you control the code, you can do
new URL(null, "classpath:some/package/resource.extension", new org.my.protocols.classpath.Handler(ClassLoader.getSystemClassLoader()))
and this will use your handler to open the connection.
But again, this is less than satisfactory, as you don't need a URL to do this - you want to do this because some lib you can't (or don't want to) control wants urls...
JVM Handler registration
The ultimate option is to register a URLStreamHandlerFactory
that will handle all urls across the jvm:
package my.org.url;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.util.HashMap;
import java.util.Map;
class ConfigurableStreamHandlerFactory implements URLStreamHandlerFactory {
private final Map<String, URLStreamHandler> protocolHandlers;
public ConfigurableStreamHandlerFactory(String protocol, URLStreamHandler urlHandler) {
protocolHandlers = new HashMap<String, URLStreamHandler>();
addHandler(protocol, urlHandler);
}
public void addHandler(String protocol, URLStreamHandler urlHandler) {
protocolHandlers.put(protocol, urlHandler);
}
public URLStreamHandler createURLStreamHandler(String protocol) {
return protocolHandlers.get(protocol);
}
}
To register the handler, call URL.setURLStreamHandlerFactory()
with your configured factory. Then do new URL("classpath:org/my/package/resource.extension")
like the first example and away you go.
JVM Handler Registration Issue
Note that this method may only be called once per JVM, and note well that Tomcat will use this method to register a JNDI handler (AFAIK). Try Jetty (I will be); at worst, you can use the method first and then it has to work around you!
License
I release this to the public domain, and ask that if you wish to modify that you start a OSS project somewhere and comment here with the details. A better implementation would be to have a URLStreamHandlerFactory
that uses ThreadLocal
s to store URLStreamHandler
s for each Thread.currentThread().getContextClassLoader()
. I'll even give you my modifications and test classes.
How to get a path to a resource in a Java JAR file
This is deliberate. The contents of the "file" may not be available as a file. Remember you are dealing with classes and resources that may be part of a JAR file or other kind of resource. The classloader does not have to provide a file handle to the resource, for example the jar file may not have been expanded into individual files in the file system.
Anything you can do by getting a java.io.File could be done by copying the stream out into a temporary file and doing the same, if a java.io.File is absolutely necessary.
Related Topics
Get an Error When Trying to Get All the Photos from Phassetcollection.Fetchassetcollections
How to Add Initializers in Extensions to Existing Uikit Classes Such as Uicolor
.Dynamictype Is Deprecated. Use 'Type(Of ...)' Instead
Need Self to Set All Constants of a Swift Class in Init
Iterate an Array W/ Explicit Object Type in Swift
Do Local Notifications Need User Permission on iOS
Xcode10 - Dyld: Library Not Loaded for Pod Installed in Framework
iOS 11 Black Bar Appears on Navigation Bar When Pushing View Controller
iOS 10 App Crashes When Trying to Save Image to Photo Library
Module File's Deployment Target Is iOS9.0 V9.0 with Xcode 7/Swift 2
Get Resource Url from Project Specific Path
How to Remove Quotes from String on Swift
How to Avoid Migration in Realmswift
Is Removing a Notificationcenter Observer That Was Created with Closure Syntax by Name Adequate