12

I have a line of code that is : File file = new File(getFile()) in a java class HandleData.java

Method - getFile() takes the value of the property fileName. And fileName is injected through application_context.xml with a bean section of the class - HandleData as below:

 <bean id="dataHandler" class="com.profile.transaction.HandleData">
 <property name="fileName" value="DataFile.xml"></property>
 </bean>

I build the project successfully and checked that - DataFile.xml is present in WEB-INF/classes. And the HandleData.class is present in WEB-INF/classes/com/profile/transacon

But when I run it it throws me filenotfound exception. If I inject the absolute path (C:\MyProjectWorkspace\DataProject\target\ProfileService\WEB-INF\classes\DataFile.xml it finds the file successfully.).

Could someone help in figuring out the proper path to be injected so that the file is taken from the classpath ?

Steer360
  • 544
  • 2
  • 7
  • 14

3 Answers3

38

While injecting a File is generally the preferred approach, you can also leverage Spring's ResourceLoader for dynamic loading of resources.

Generally this is as simple as injecting the ResourceLoader into your Spring bean:

@Autowired
private ResourceLoader resourceLoader;

Then to load from the classpath:

resourceLoader.getResource("classpath:myfile.txt");
helmy
  • 9,068
  • 3
  • 32
  • 31
3

You should have:

<property name="fileName" value="classpath:DataFile.xml" />

And it should be injected as a org.springframework.core.io.Resource similar to this answer

Community
  • 1
  • 1
Lucas
  • 14,227
  • 9
  • 74
  • 124
  • Hi did you mean – Steer360 Mar 08 '13 at 15:54
  • I actually tried that, it shows me FileNotFoundException as classpath:DataFile.xml cannot be found. – Steer360 Mar 08 '13 at 15:57
  • @Steer360, are you sure? `classpath:DataFile.xml` says find DataFile.xml in the root of anything in the classpath of which WEB-INF/classes is one element... – Lucas Mar 08 '13 at 16:00
  • yes. The line - File file = new File(getFile()) is called.So it is getting the value classpath:DataFile.xml now. I just checked with a print statement. – Steer360 Mar 08 '13 at 16:09
  • Thanks lucas, Creating new file or getResourceAsStream takes file name as parameter , i think thats why it does not recognise classpath: with it? I have used classpath: with the filename for annotation of @ContextConfiguration or other reference to the file through Context annotation though... – Steer360 Mar 08 '13 at 17:13
  • @Steer360, I updated my answer to include a reference to another answer that shows the code side of this approach – Lucas Mar 08 '13 at 17:46
  • Thanks , I will try that out, will love to refer classpath:filename from spring injection. – Steer360 Mar 08 '13 at 18:41
3

Since OP is injecting Only the fileName through spring, still want to create the File Object through code , You should Use ClassLoadeer to read the file

Try this

InputStream is =  HandleData.class.getClassLoader().getResourceAsStream(getFile()));

Edit

Heres the remainder of code , to read the file

BufferedInputStream bf = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bf);

while (dis.available() != 0) {
    System.out.println(dis.readLine());
}

Edit 2

Since you want it as File Object, to get hold of the FileInputStream

try this

 FileInputStream fisTargetFile = new FileInputStream(new File(HandleData.class.getClassLoader().getResource(getFile()).getFile()));
Sudhakar
  • 4,823
  • 2
  • 35
  • 42
  • OP is injecting Only the fileName through spring, He would still want to create the File Object through code – Sudhakar Mar 08 '13 at 15:38
  • I am trying to use your suggestion and use InputStream instead. Currently I am passing the fileName as below: FileInputStream fisTargetFile = new FileInputStream(new File(fileName)); So InputStream does not work for this piece. – Steer360 Mar 08 '13 at 16:21
  • Yes. It worked! Could not use classpath:DataFile.xml (I am surprised) in the property value. I think that works when we refer the context with annotation. So I kept the value as "DataFile.xml". I used InputStream is = HandleData.class.getClassLoader().getResourceAsStream(getFile())); and passed is to the calling method which is IOUtils from org.apache.commons.io and takes InputStream Parameter as well !! Thanks a lot. – Steer360 Mar 08 '13 at 17:08