Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reference a file that is placed in the WEB-INF folder when using Arquillian?

I am using maven and the standard directory layout. So I have added a testdata.xml file in the src/test/resources folder, and I also added it as:

.addAsWebInfResource("testdata.xml", "testdata.xml")

in the deployment method, and I have confirmed that it is there. This will make the file appear in /WEB-INF/testdata.xml. Now I need to have a reference to this file in my code and I tried several different getClass().getResourceAsStream(...) and failing again and again so I need some advise now.

I need it for my DBUnit integration test. Is this not possible?

like image 346
LuckyLuke Avatar asked Oct 28 '12 20:10

LuckyLuke


People also ask

What is WEB-INF folder?

WEB-INF. This directory, which is contained within the Document Root, is invisible from the web container. It contains all resources needed to run the application, from Java classes, to JAR files and libraries, to other supporting files that the developer does not want a web user to access.

Where does the META INF folder go?

Basically it has to be in your classpath(under /META-INF/ ). You can manually enable it in eclipse by configuring properties. If your project is maven based, then it should be automatically picked from /src/main/resources/META-INF/ folder (provided entities are under the same hood).

Where can I find WEB-INF?

WEB-INF folder is under public_html folder. You can configure and add your content to your site yourself with. class files. In this directory you should place your .


2 Answers

Option A) Use ServletContext.getResourceXXX()

You should have a Aquillarian MockHttpSession and a MockServletContext. E.g.:

@Test
   public void myTest()
   {
      HttpSession session = new MockHttpSession(new MockServletContext());
      ServletLifecycle.beginSession(session);

      ..testCode..

      // You can obtain a ServletContext (will actually be a MockServletContext 
      // implementation):
      ServletContext sc = session.getServletContext();
      URL url = sc.getResource("/WEB-INF/testdata.xml")
      Path resPath = new Path(url);
      File resFile = new File(url);
      FileReader resRdr = new FileReader(resFile);
      etc...

      ..testCode..

      ServletLifecycle.endSession(session);
   }

You can create resource files & subdirectories in:

  1. the web module document root - resources are accessible from the browser and from classes
  2. WEB-INF/classes/ - resources are accessible to classes
  3. WEB-INF/lib/*.jar source jar - accessible to classes
  4. WEB-INF/lib/*.jar dedicated resource-only jar - accessible to classes
  5. WEB-INF/ directly within directory - accessible to classes. This is what you are asking for.

In all cases the resource can be accessed via:

URL url = sc.getResource("/<path from web doc root>/<resourceFileName>");
OR    
InputStream resIS = sc.getResourceAsStream("/<path from web doc root>/<resourceFileName>");

>

These will be packaged into the WAR file and may be exploded into directories on the deployed app server OR they may stay within the WAR file on the app server. Either way - same behaviour for accessing resources: use ServletContext.getResourceXXX().

Note that as a general principle, (5) the top-level WEB-INF directory itself is intended for use by the server. It is 'polite' not to put your web resources directly in here or create your own directory directly in here. Instead, better to use (2) above.

JEE5 tutorial web modules JEE6 tutorial web modules

Option B): Use Class.getResourceXXX()

First move the resource out of WEB-INF folder into WEB-INF/classes (or inside a jar WEB-INF/lib/*.jar).

If your test class is:

  • com.abc.pkg.test.MyTest in file WEB-INF/classes/com/abc/pkg/test/MyTest.class

And your resource file is

  • WEB-INF/classes/com/abc/pkg/test/resources/testdata.xml (or equivalent in a jar file)

Access File using Relative File Location, via the Java ClassLoader - finds Folders/Jars relative to Classpath:

java.net.URL resFileURL = MyTest.class.getResource("resources/testdata.xml");
File resFile = new File(fileURL);    
OR
InputStream resFileIS = 
     MyTedy.class.getResourceAsStream("resources/testdata.xml");

Access File Using full Package-like Qualification, Using the Java ClassLoader - finds Folders/Jars relative to Classpath:

java.net.URL resFileURL = MyTest.class.getResource("/com/abc/pkg/test/resources/testdata.xml");
File resFile = new File(fileURL);        
OR 
InputStream resFileIS = 
     MyTest.class.getResourceAsStream("/com/abc/pkg/test/resources/testdata.xml");   
OR 
java.net.URL resFileURL = MyTest.class.getClassLoader().getResource("com/abc/pkg/test/resources/testdata.xml");
File resFile = new File(fileURL);       
OR 
InputStream resFileIS = 
     MyTest.class.getClassLoader().getResourceAsStream("com/abc/pkg/test/resources/testdata.xml");

Hope that nails it! @B)

like image 138
Glen Best Avatar answered Nov 04 '22 08:11

Glen Best


The way to access files under WEB-INF is via three methods of ServletContext:

  1. getResource("/WEB-INF/testdata.xml") gives you a URL
  2. getResourceAsStream gives you an input stream
  3. getRealPath gives you the path on disk of the relevant file.

The first two should always work, the third may fail if there is no direct correspondence between resource paths and files on disk, for example if your web application is being run directly from a WAR file rather than an unpacked directory structure.

like image 22
Ian Roberts Avatar answered Nov 04 '22 10:11

Ian Roberts