I'm trying to access GeoLiteCity File, it's working on my local machine but unable to get path on the cloud (Azure).
file saved exactly hierarchy like:
/src/main/resources/database/GeoLiteCity.dat
My Code:
void getFile() {
if (this.file == null) {
try {
URL url = this.getClass().getClassLoader().getResource("database/GeoLiteCity.dat");
this.file = new File(url.toURI());
System.out.println(file.getPath().toString());
} catch (Exception ex) {
System.out.println(file.getPath().toString(),ex);
}
}
}
Assumption that the code is a part of Java WebApp running on Tomcat. Per my experience, if you want to get the resource via the method this.getClass().getClassLoader().getResource("<the data file path relative to the root classes path>"), so please make sure the data file GeoLiteCity.dat under the path webapps/<your-webapp-name>/WEB-INF/classes/database/.
If your webapp was deployed on Azure WebApp, I think you can try to use the absolute path of data file on Azure WebApp, such as D:/home/site/wwwroot/webapps/<your-webapp-name>/<the data file path>, and only use new File("<the absolute path of data file>").
Related
I want to access a file inside a resource folder of the current jar running.
The file is inside of My_app.jar where is located to /apps/dashboard/
I tried to access it like this
String customScriptPath = "script/template.sh";
public String getTemplatePath() {
Resource temp= new ClassPathResource(this.customScriptPath, this.getClass().getClassLoader());
try {
File templateFile = temp.getFile();
logger.info("Script template path = "+templateFile.getAbsolutePath());
return templateFile.getAbsolutePath();
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
return null;
}
and I got this error
class path resource [script/template.sh] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/apps/dashboard/My_app.jar!/BOOT-INF/classes!/script/template.sh
You can't use File to access the template.sh. File is used to reference files in the file system. In your case, you are trying to reference something inside a jar file.
If you want to read content of template.sh, take a stream using Resource.getInputStream(). If you want to log location of the file, use Resource.getURL().
I've a JavaFX application that I packaged it using antBuild to build a single installer .exe file, my app have some configuration files that was placed in the root of the project this way i load them from the root of the project in order to they can be place beside the .jar file and could be changable:
try {
File base = null;
try {
base = new File(MainApp.class.getProtectionDomain().getCodeSource().getLocation().toURI())
.getParentFile();
} catch (URISyntaxException e) {
System.exit(0);
}
try {
File configFile = new File(base, "config.properties");
}
so after packaging the app even if I put the files manually in the same place with jar file, again the app can not recognize them and put into error.
So what is the proper way to store and where to store some sort of config files and how to add them to the installer to put it to right place during installation?
If your application is bundled as a jar file, then MainApp.class.getProtectionDomain().getCodeSource().getLocation().toURI() will return a jar: scheme URI. The constructor for File taking a URI assumes it gets a file: scheme URI, which is why you are getting an error here. (Basically, if your application is bundled as a jar file, the resource config.properties is not a file at all, its an entry in an archive file.) There's basically no (reliable) way to update the contents of the jar file bundling the application.
The way I usually approach this is to bundle the default configuration file into the jar file, and to define a path on the user file system that is used to store the editable config file. Usually this will be relative to the user's home directory:
Path configLocation = Paths.get(System.getProperty("user.home"), ".applicationName", "config.properties");
or something similar.
Then at startup you can do:
if (! Files.exists(configLocation)) {
// create directory if needed
if (! Files.exists(configLocation.getParent())) {
Files.createDirectory(configLocation.getParent());
}
// extract default config from jar and copy to config location:
try (
BufferedReader in = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/config.properties")));
BufferedWriter out = Files.newBufferedWriter(configLocation);) {
in.lines().forEach(line -> {
out.append(line);
out.newLine();
});
} catch (IOException exc) {
// handle exception, e.g. log and warn user config could not be created
}
}
Properties config = new Properties();
try (BufferedReader in = Files.newBufferedReader(configLocation)) {
config.load(in);
} catch (IOException exc) {
// handle exception...
}
So this checks to see if the config file already exists. If not, it extracts the default config from the jar file and copies its content to the defined location. Then it loads the config from the defined location. Thus the first time the user runs the application, it uses the default configuration. After that, the user can edit the config file and subsequently it will use the edited version. You can of course create a UI to modify the contents if you like. One bonus of this is that if the user does something to make the config unreadable, they can simply delete it and the default will be used again.
Obviously this can be bullet-proofed against exceptions a little better (e.g. handle case where the directory is unwritable for some reason, make the config file location user-definable, etc) but that's the basic structure I use in these scenarios.
I create a dynamic web app project using JSP/Servlet with eclipse. And I want to create a copy of "db.xls" file in the same place.
I try to create a copy of the "db.xls", the copy will named out.xls but it won't. These files should be located inside the same folder "files". My code compile, db.xls is correctly read, but file out.xls is not created.
What's wrong with my method ? Please help !
public void readExcel()
{
try{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL url1 = classLoader.getResource("");
// read db.xls
wbook = Workbook.getWorkbook(new File(url1.getPath()+"/db.xls"));
// create a copy of db.xls nammed out.xls
wwbCopy = Workbook.createWorkbook(new File(url1.getPath()+"/out.xls"), wbook);
shSheet = wwbCopy.getSheet(0);
}
catch(Exception e)
{
e.printStackTrace();
}
}
I move the file "db.xls" inside WEB-INF and use getServletContext().getRealPath("/WEB-INF") but the output file "out.xls" still not created.
public void readExcel()
{
try{
// ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// URL url1 = classLoader.getResource("");
String tomcatRoot = getServletContext().getRealPath("/WEB-INF");
wbook = Workbook.getWorkbook(new File(tomcatRoot+"/db.xls"));
wwbCopy = Workbook.createWorkbook(new File(tomcatRoot+"/out.xls"), wbook);
shSheet = wwbCopy.getSheet(0);
}
catch(Exception e)
{
e.printStackTrace();
}
}
System.out your files and you'll see what's wrong
System.out.println(new File(tomcatRoot+"/db.xls").getAbsolutePath());
System.out.println(new File(tomcatRoot+"/out.xls").getAbsolutePath());
You expect the file to be you project directory but it isnt read/writen from/to that location because you have set up the files forlder as source folder in eclipse, so it is part our yours assempbly and lands in the classpath where you can read from a resource, i.e. using classloader and getResource / getResourceAsStream but you cannot and should not write to it, for several resons, most obvious is that your web app might not be unpacked from a war files.
In fact, you dont know where you are reading/writing your files to/from.
You might package your file with the war file and read from it, this is correct. But for writing the best is to have an explicite location on the filesystem where you can write your output files. check this answer for how you could go abut it using context init parameter
check the WEB-INF/classes folder, it might be in there
I think your missing write and close statements.
Try:
wwbCopy.write();
wwbCopy.close();
In order to read files within a web application, the files need to be stored somewhere under the WEB-INF folder, otherwise they won't be deployed as part of the application.
Once you've moved the folders into there you can use the following method within a servlet:
String tomcatRoot = getServletContext().getRealPath("/");
This will give you the root of the web application. Then you must build the path (including the WEB-INF folder) from there:
String sourceFile = tomcatRoot + "/WEB-INF/folder/source.file"
String targetFile = tomcatRoot + "/WEB-INF/folder/target.file"
EDIT: I originally stated that getRealPath() would give you the WEB-INF location. It doesn't, it gives the parent folder.
On local machine (localhost), in a java class file of a web application, I am giving file path as under.
JRBeanCollectionDataSource bean = new JRBeanCollectionDataSource(al);
try {
print = JasperFillManager.fillReport("D://vivek's//powerSpace//report//bus.jasper",
new HashMap(), bean);
} catch (JRException e) {
e.printStackTrace();
}
return al;
}
But when this web application is hosted on server, how to give the absolute path of the file.
Use the resources for this.
EG:
put the bus.jasper into resources folder of your webapp, then use:
InputStream resource = getClass().getClassLoader().getResourceAsStream("bus.jasper");
and work with the InputStream from there.
If the API of the class you're using is so lame that it needs the filepath use
ConstantDataManager.class.getClassLoader().getResource("bus.jasper").getPath();
The second solution doesn't work well on Weblogic though.
I create ImageServlet to refer to videos out of my web application scope.
The location of all of my videos are on a intranet location that could be reached from any computer in the intranet:
String path = "\\myip\storage\ogg\VX-276.ogg"
In my application, when I write it as URL - it can't display it!
If I try to open it with chrome it automatically changes it to file://myip/storage/ogg/VX-276.ogg and the file is being displayed.
I tried to do so: file:////odelyay_test64/storage/ogg/
as well but Java converts the string to: file:\myip\storage\ogg\VX-276.ogg which does not exist!
What is the correct way to refer to it?
EDITED
I create a small test:
String path = "file://myip/storage/ogg/VX-276.ogg";
File file = new File(path);
if (file.exists())
System.out.println("exists");
else {
System.out.println("missing" + file.getPath());
}
and I get:
missing file:\myip\storage\ogg\VX-276.ogg
As you can see the slashes are being switched
As per your previous question, you're referencing the resource in a HTML <video> tag. All URLs in the HTML source code must be http:// URLs (or at least be relative to a http:// URL). Most browsers namely refuse to load resources from file:// URLs when the HTML page is itself been requested by http://. You just need to let the URL point to the servlet. If the servlet's doGet() method get hit, then the URL is fine and you should not change it.
Your concrete problem is in the way how you open and read the desired file in the servlet. You need to ensure that the path in File file = new File(path) points to a valid location before you open a FileInputStream on it.
String path = "file://myip/storage/ogg/VX-276.ogg";
File file = new File(path);
// ...
If the servlet code is well written that it doesn't suppress/swallow exceptions and you have read the server logs, then you should have seen an IOException such as FileNotFoundException along with a self-explaining message in the server logs whenever reading the file fails. Go read the server logs.
Update as per the comments, it turns out that you're using Windows and thus file:// on a network disk isn't going to work for Java without mapping it on a drive letter. You need to map //myip on a drive letter first, for example X:.
String path = "X:/storage/ogg/VX-276.ogg";
File file = new File(path);
// ...
in the end I used VFS library of apache and my code looks like this:
public static void main(String[] args) {
FileSystemManager fsManager = null;
String path = "\\\\myip\\storage\\ogg\\VX-276.ogg";
try {
fsManager = VFS.getManager();
FileObject basePath;
basePath = fsManager.resolveFile("file:" + path);
if (basePath.exists())
System.out.println("exists");
else {
System.out.println("missing" + basePath.getURL());
}
} catch (FileSystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In this way, I don't need to create a driver for each user of the system and it allows me not to depend on operation system!