Hibernate can't read hibernate.cfg.xml - java

I'm using Hibernate 4.1 in GWT app running on Jetty 1.6
Got the next code to start up hib.instance:
Configuration configuration = new Configuration().configure(ABS_PATH_TO_CONFIG+File.separator+"hibernate.cfg.xml");
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
First line gives me an error:
org.hibernate.HibernateException: ...hibernate.cfg.xml not found
at org.hibernate.internal.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:173)
But I checked hibernate.cfg.xml availability just before loading hib.config:
File conf = new File(ABS_PATH_TO_CONFIG+File.separator+"hibernate.cfg.xml");
System.out.println(conf.canRead());
Sysout returns true.
Looking into source of ConfigHelper.getResourceAsStream with break point in it:
InputStream stream = null;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader!=null) {
stream = classLoader.getResourceAsStream( stripped );
}
if ( stream == null ) {
stream = Environment.class.getResourceAsStream( resource );
}
if ( stream == null ) {
stream = Environment.class.getClassLoader().getResourceAsStream( stripped );
}
if ( stream == null ) {
throw new HibernateException( resource + " not found" );
}
I'm doing something wrong (doesn't understand something) or it's really no xml loaders here?

There are several things wrong here.
First of all, this:
Configuration configuration = new Configuration().configure(ABS_PATH_TO_CONFIG+File.separator+"hibernate.cfg.xml");
does not do what you think it does.
Your example is not checking the availability of the configuration file. It is checking whether the file exists on the file system, not in the classpath. This difference is important.
Without knowing more about how you build and deploy your webapp or how you have your files organized, it's hard to give you any more concrete advice, other than try copying the "hibernate.cfg.xml" to the root of your classpath, and just passing that to the configure() method. That should work.
So your code should be:
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
And your hibernate.cfg.xml file should be in the root of your classpath.
Alternatively, if you're using Maven, just put it under the "resources" folder and Maven should do the rest for you.

This way custom-located config file is loaded:
File conf = new File(ABS_PATH_TO_CONFIG+File.separator+"hibernate.cfg.xml");
Configuration configuration = new Configuration().configure(conf.getAbsoluteFile());
FYC: configure() method are overloaded

I'll tell you that program won't never treat you.
about your problem, you can do like this to get the path of the config file:
String basePath = PropertiesUtil.class.getResource("/").getPath();
then read it
InputStream in = new FileInputStream(basePath + fileName);
Good luck!

Related

Unable to read file from spring boot .jar

I want to access file on my classpath called reports/invoiceSweetChoice.jasper in jar on production server. Whatever I do I get null.
I have tried this.getClass().getResourceAsStream("reports/invoiceSweetChoice.jasper"), tried via InputStream etc. I have printed out content of System.getProperty("java.class.path") and it is empty. Not sure how is that possible. Do you have any suggestion how to resolve this ?
In manifest.mf, the classpath is defined using the class-path key and a space-delimited list of files, as follows:
MANIFEST.MF at root of jarfile.
Class-Path: hd1.jar path/to/label007.jar path/to/foo.jar
If there are spaces in the jar filename, you should enclose them in quotes.
If it's a webapp, the reports path should be in your BOOT-INF subdirectory of your classpath -- this is automatically performed by maven if you put it in src/main/resources in the standard layout.
EDIT:
Now that you've clarified what you're trying to do, you have 2 approaches. Like I said above, you can grab the file from the BOOT-INF subdirectory of your webapp or you can enumerate the entries in the jar until you find the one you want:
JarInputStream is = new JarInputStream(new FileInputStream("your/jar/file.jar"));
JarEntry obj = null
while ((obj = is.getNextJarEntry()) != null) {
JarEntry entry = (JarEntry)obj;
if (entry.getName().equals("file.abc")) {
ByteArrayOutputStream baos = new ByetArrayOutputStream();
IOUtils.copy(jarFile.getInputStream(entry), baos);
String contents = new String(baos.toByteArray(), "utf-8");
// your entry is now read into contents
}
}
#Autowired private ResourceLoader resLoad;
void someMethod() {
Resource r = resLoad.getResource("classpath:reports/file.abc");
r.getInputStream()...
...

Java: Getting resource path of the main app instead of jar's

A lot has been discussed already here about getting a resource.
If there is already a solution - please point me to it because I couldn't find.
I have a program which uses several jars.
To one of the jars I added a properties file under main/resources folder.
I've added the following method to the jar project in order to to read it:
public void loadAppPropertiesFile() {
try {
Properties prop = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String resourcePath = this.getClass().getClassLoader().getResource("").getPath();
InputStream stream = loader.getResourceAsStream(resourcePath + "\\entities.properties");
prop.load(stream);
String default_ssl = prop.getProperty("default_ssl");
}catch (Exception e){
}
}
The problem (?) is that resourcePath gives me a path to the target\test-clasess but under the calling application directory although the loading code exists in the jar!
This the jar content:
The jar is added to the main project by maven dependency.
How can I overcome this state and read the jar resource file?
Thanks!
I would suggest using the classloader used to load the class, not the context classloader.
Then, you have two options to get at a resource at the root of the jar file:
Use Class.getResourceAsStream, passing in an absolute path (leading /)
Use ClassLoader.getResourceAsStream, passing in a relative path (just "entities.properties")
So either of:
InputStream stream = getClass().getResourceAsStream("/entities.properties");
InputStream stream = getClass().getClassLoader().getResourceAsStream("entities.properties");
Personally I'd use the first option as it's briefer and just as clear.
Can you try this:
InputStream stream = getClass().getClassLoader().getResourceAsStream("entities.properties")

how to read external file from a class in the JAR

File Structure:
/web-project
|
|---/WEB-INF/a.jar
|
|---/META-INF/resources/b.properties
A.class which is located in a.jar wants to read /META-INF/resources/b.properties
I think that both a.jar and b.properties are under the same class loader (because they are in the same web context)
I've tried the following ways to try to achieve my purpose but not work.
InputStream is = null;
ClassLoader[] loaders = { Thread.currentThread().getContextClassLoader(),
ClassLoader.getSystemClassLoader(), getClass().getClassLoader() };
ClassLoader currentLoader = null;
for (int i = 0; i < loaders.length; i++) {
if (loaders[i] != null) {
currentLoader = loaders[i];
is = currentLoader.getResourceAsStream("/META-INF/resources/b.properties");
if (is != null) { // is is always null no matter what ways I used.
break;
}
}
}
I have no idea where I got mistakes.
Please guide me to the right path.
Thank you very much.
=====UPDATED=====
First of all , thanks for all people (especially #Ravi & #EJP) who comment, answer and discuss this question.
Below are what I've tried based on the discussion.
InputStream is = null;
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
is = A.class.getClassLoader().getResourceAsStream(url.getPath() + "../../../META-INF/resources/b.properites"); // is = null
is = new FileInputStream(url.getPath() + "../../../META-INF/resources/b.properites"); // is != null
It seems that I should use FileInputStream to get resources outside of the JAR instead of using getResourceAsStream()?
=====UPDATED 2=====
Eventually, I figured it out with the following solution.
context.getResourceAsStream("/META-INF/resources/b.properties");
based on the prerequisite below:
a.jar/b.properties are in the same context
A.class can obtain the ServletContext object
It seems that I should use FileInputStream to get resources outside of the JAR instead of using getResourceAsStream()?
Resources are in the JAR file, by definition. Anything outside it is not a resource but a file, and you should use FileInputStream or FileReader to read it. You can use
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
to get the location of the JAR file, so if you distribute the file in the same directory you just have to do a little path-mangling to get the path of the file from it.
You can solve this issue by first validating the path for your jar file. You can execute following line of code and check the path
getClass().getProtectionDomain().getCodeSource().getLocation();
Since, you resource file is located outside of your jar file, you need to change the path relative to your jar file.
Properties mainProperties = new Properties();
FileInputStream file = new FileInputStream("<relative-path>/META-INF/resources/b.properties");
mainProperties.load(file);
file.close();
I have tested above code with below folder structure
/web-project
|
|---/WEB-INF/a.jar
|
|---/test/resources/b.properties

Unable to open properties file in servlet via a helper class

I have a class,in which ther is a func,which opens a properties file. When i write main in the same class & call that function,i am able to open the properties file n read. but, when i am tying to call the same func in my servlet by creating instance to that class, i get file not found exception.
This is the function, which i have written in my class to read properties file. And both my class and servlet are in src folder. I am using eclipse IDE.
Code:
private void readPropertiesFileAndFieldListData() {
String PROP_FILE = "./src/fields.properties";
try {
FileReader reader = new FileReader(PROP_FILE);
BufferedReader br = new BufferedReader(reader);
ArrayList<String> field = new ArrayList<String>();
while ((str = br.readLine()) != null) {
if (!str.startsWith("#") && str.trim().length() > 0) {
// System.out.println(str);
field.add(str);
count++;
}
}
}
You're relying on the current working directory of the disk file system path. The current working directory is dependent on how the application is started and is not controllable from inside your application. Relying on it is a very bad idea.
The normal practice is to put that file in the classpath or to add its path to the classpath. Your file is apparently already in the classpath (you placed it in the src folder), so you don't need to change anything else. You should should just get it from the classpath by the class loader. That's more portable than a disk file system path can ever be.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("fields.properties");
// ...
See also:
getResourceAsStream() vs FileInputStream
Unrelated to the concrete problem, you're basically reinventing the java.util.Properties class. Don't do that. Use the following construct:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("fields.properties");
Properties properties = new Properties();
properties.load(input);
// ...
PLease write a small test, for printing the file path of "PROP_FILE" to the log or console.
it seems, that you relativ path is incorrect.
Your relative path starting point can change, depending on where your *.exe file is started.
Your test should print
File tFile = new File(PROP_FILE);
// print tFile.getAbsolutePath()
Its better to get a special class by calling
SomeClass.class.getResource(name)
Eclipse RCP from the Bundle
Bundle.getResource(ResourcePathString)
EDIT:
Please check, whether the resource is part of your *.jar. It could be, that you missed to add it to the build.properties file.
Check whether the file is existing, before you read the properties file.

Unable to read Java File from JSF

The directory structure of my application is as follows:-
My App
++++++ src
++++++++com
++++++++++readProp.java
++++++++resource
++++++++++message.properties
I am trying to read the file as follows:-
public Static final string FilePath="resource.message.properties"
Here the code to read the file. I tried using the following two techniques but to no use...
File accountPropertiesFile = new File(FacesContext.getCurrentInstance()
.getExternalContext().getRequestContextPath()
+ FilePath);
properties.load(externalContext.getResourceAsStream(FilePath));
But none yeild any sucess while reading through the Bean class. please help...
Your properties file is in the classpath. The java.io.File only understands the local disk file system structure. This is not going to work. You need to get it straight from the classpath by the classloader.
Here's a kickoff example:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("/resources/messages.properties");
if (input != null) {
Properties properties = new Properties();
try {
properties.load(input);
} finally {
input.close();
}
}
I don't know if this is your problem, but you should try using slashes instead of periods, since they're stored as actual folders in the filesystem.

Categories

Resources