WebSphere Liberty: Access properties file from library jar file - websphere-liberty

I am running on WebSphere Liberty 17.0.0.4. Deployed a web application and custom authentication module which is located under {wlp_install_dir}/lib directory. And that jar file is marked as library in server.xml file. Here is how it looks in server.xml
<library id="CustomLoginModuleLib">
<fileset dir="${wlp.lib.dir}" includes="custom_auth.jar"/>
</library>
Now the thing is, I want to use .properties file located inside custom_auth.jar file to the web application.
Have tried following code snippet to access:
this.getClass().getResourceAsStream("location/of/package/file.properties");
ClassLoader.getSystemResourceAsStream("location/of/package/file.properties");
But, neither works.
Any idea how can we access properties file located in library jar file.

Please see my response to this same question on dwAnswers at:
https://developer.ibm.com/answers/questions/444708/how-to-access-properties-file-located-in-library-j.html
To summarize the answer from there:
(1) I would never recommend putting user-provided JAR files in the {wlp_install_dir}/lib directory - that dir is only intended for IBM-provided JAR files. Instead, I would suggest putting your custom_auth.jar in your server directory or in a shared directory.
(2) You will need to associate the shared library with your application(s) like so:
<application location ="{appName}.war"> <!-- or {appName}.ear -->
<classloader commonLibraryRef="CustomLoginModuleLib" />
</application>
Depending on your needs, you can use a commonLibraryRef (as shown) or a privateLibraryRef. More info on shared libraries can be found here: https://www.ibm.com/support/knowledgecenter/SSD28V_9.0.0/com.ibm.websphere.wlp.core.doc/ae/cwlp_sharedlibrary.html
(3) As for loading the file in the Java code, your first line will work - assuming that this refers to an instance of a class in your application. I also assumes that the path you pass to the getResourceAsStream method is the same as the path to the file inside the library JAR.
Hope this helps, Andy

Related

How to override server.xml file fo tomcat from spring project

How can I override server.xml or context.xml file of tomcat 8 from project? Because I am using data source in server.xml.
You cannot override the server.xml from your project. On the other hand you can override context.xml. You can do so by (c/p from docs)
In an individual file at /META-INF/context.xml inside the application
files. Optionally (based on the Host's copyXML attribute) this may be
copied to $CATALINA_BASE/conf/[enginename]/[hostname]/ and renamed to
application's base file name plus a ".xml" extension.
As described, to override context.xml you should add a META-INF to your webapp's root and place inside your context.xml. Note that in order for your projects context.xml to take effect, there should not be already set context.xml for that particular project inside tomcat instance
In individual files (with a ".xml" extension) in the
$CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The context
path and version will be derived from the base name of the file (the
file name less the .xml extension). This file will always take
precedence over any context.xml file packaged in the web application's
META-INF directory.

External web app location does not create directory under webapps in Tomcat

So far we have been using Tomcat 6 where we specify the war to be deployed in context.xml file under $CATALINA_HOME/conf/Catalina/localhost as application1-context.xml, application2-context.xml. etc.
example application1-context.xml
<Context path="/myapps/app1" docBase="C:\warfiles\appOne.war"
debug="0" privileged="true">
<Loader className="MyCustomApplicationLoader"/>
<Logger className="org.apache.catalina.logger.SystemOutLogger" verbosity="4" timestamp="true"/>
</Context>
This would create a folder myapps#app1 under $CATALINA_HOME/webapps folder.
But since migrating to Tomcat7, this does not happen any more.
Unless I have the war file "appone.war" directly under the tomcat appBase directory i.e. $CATALINA_HOME/webapps my war will not be unpacked into a folder under $CATALINA_HOME/webapps directory.
I have read this apache bug report:
https://issues.apache.org/bugzilla/show_bug.cgi?id=51294&quot%3B&gt%3B51294&lt%3B/a&gt%3B
Question:
Is there any way we can force this behavior in tomcat 7?
It sounds like this issue has been fixed in Tomcat version 7.0.48 which, at the time of writing, is still in development. It's also been added to version 8.
Edit: I have managed to resolve this without having to wait for/use 7.0.48. In your context.xml file add unpackWAR="false" and specify the virtualClasspath attribute so it points to your target\classes folder like so:
<?xml version="1.0" encoding="utf-8"?>
<Context docBase="(path to .war file)">
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="(path to folder contain .class files,
usually {project folder}\target\classes\)"
searchExternalFirst="true"
unpackWAR="false" />
</Context>
searchExternalFirst means that the class loader will look in your virtualClasspath folder before looking in the WEB-INF directory.
unpackWAR is set to false because your war file will already be exploded in the /target/classes folder so there's no need for Tomcat to do it as well.
Hopefully this helps you too.
Try <Context unpackWARs="true" ...
Files under conf/catalina/... should not be changed manual. They are created automatically if not exists on first start of the webapp. You should never change these files, delete them instead and let them be created new from tomcat itself (they are composed by the war's /META-INF/context.xml-File if exists).

spring junit load application context for tests

I've got some XML files under my WEB-INF directory:
lyricsBaseApp-servlet.xml
hibernate.xml
dataSource.xml
beans.xml
the servlet xml imports other xml files:
<import resource="dataSource.xml"/>
<import resource="hibernate.xml"/>
<import resource="beans.xml"/>
I would like my junit4 JukeboxTest class to include entire spring configuration. Using default filename I have created a JukeboxTest-content.xml file. And finally, I do not know what to put there...
I've tried:
<import resource="/WEB-INF/dataSource.xml"/>
<import resource="/WEB-INF/hibernate.xml"/>
<import resource="/WEB-INF/beans.xml"/>
or
<import resource="classpath:./WEB-INF/dataSource.xml"/>
<import resource="classpath:./WEB-INF/hibernate.xml"/>
<import resource="classpath:./WEB-INF/beans.xml"/>
and some other ideas but all failed. Could someone point me how to access those files and what way spring interprets those filepaths?
Option 1 (should be preferred as it's the best practice):
Refactor your config files under WEB-INF and move the common parts (that you want to access also from integration tests) to src/main/resources/. Then write test specific configuration files in src/test/resources/ (if you only need to import several different config files from src/main to assemble your test context, then skip this, and use #ContextConfiguration preferably).
Option 2 (hack):
Use references like:
#ContextConfiguration("file:src/main/webapp/WEB-INF/dataSource.xml")
Option 3 (hack):
If you have a Maven project, you can configure the maven-surefire-plugin (used in the test phase) to declare src/main/webapp as an additional classpath element during test execution.
The latter two options are considered as hack, because files under src/main/webapp are simply not supposed to be on the classpath.
Now the detailed explanation:
The reason why you can't refer to these files as classpath:/WEB-INF/*.xml is that they are indeed not on the classpath. It's important to understand how your webapp is packaged, and what exactly ends up on the classpath. Assuming a default Maven project structure:
Java classes from src/main/java go to /WEB-INF/classes after compilation.
Resources from src/main/resources go to /WEB-INF/classes as well.
Project dependencies go to /WEB-INF/lib.
Everything you have in src/main/webapp goes to / (root of the package). This means that all files from src/main/webapp/WEB-INF go to /WEB-INF, of course.
The most important thing to know is that the classpath will only contain /WEB-INF/classes and one entry for each jar in /WEB-INF/lib. Consequently, resources outside these two locations are completely invisible for the classloader. This is also true for the xml config files directly under /WEB-INF, which is why the reference classpath:/WEB-INF/dataSource.xml will never work.
You may ask yourself, how the hell are then these xml config files loaded by Spring if they are not reachable from the classpath? The answer is simple: When you start your webapp (as opposed to executing just unit/integration tests), it is running in a Servlet Container which provides access to the ServletContext (an actual class from the Servlet API), so it uses ServletContext.getResourceAsStream() to load these files. The key for understanding is the following quote from the javadoc of this method:
This method is different from java.lang.Class.getResourceAsStream, which uses a class loader. This method allows servlet containers to make a resource available to a servlet from any location, without using a class loader.
Sorry this become way too long, but that's the whole story...
try this
#ContextConfiguration(locations = {"classpath:**/dataSource.xml",
"classpath:**/hibernate.xml",
"classpath:**/WEB-INF/beans.xml"})

Spring load parts of one config with different loaders from file and classpath

Is it possible load custom part of config from file and automatically load other part of config from classpath, placed inside jar?
I have command line apllication written on java with spring 2.5.6 framework.
Config of apllication consist from 2 parts:
bigApplicationContext.xml
customConfig.xml with import of bigApplicationContext.xml
bigApplicationContext has references to some beans from customConfig.
I placed bigApplicationContext and default customConfig inside jar. Configs loaded by ClassPathXmlApplicationContext. It's OK
Troubles goes when I want provide additional command line option for my application --pathToCustomConfig
I want to load custom part of config from file and automatically load other part of config from bigApplicationContext, placed inside jar.
Is it possible? Now I have
Configuration problem: Failed to import bean definitions from relative
location
Found solution with using
<import resource="classpath:applicationContext.xml" />
I used
<import resource="applicationContext.xml" />

How do I include two files of the same name in my spring application context?

Not sure if this has an answer, but here goes. I'm using JUnit 4.8.1 to test my Spring 3.1.0.RELEASE project. I have two JAR files on my classpath. Within each, there are files of identical names -- /module/rootContext.xml .
In my testApplicationContext.xml file (my Spring context file for my JUnit tests), is it possible to include each of those? Right now, the only thing I know how to do is
<import resource="classpath:/module/rootContext.xml" />
but I don't know how to specify the exact JAR file where each file lives.
Because I'm dealing with code that's not my own, it is not an option to change the names of the XML files within the JARs.
If you want to include both files simultaneosly, you can do it as follows:
<import resource="classpath*:/module/rootContext.xml" />
See also:
4.7.2.2 The classpath*: prefix

Resources