Tomcat - FileNotFoundException - java

I have a web application deployed on my tomcat server.
My folder structure is TOMCAT_HOME/webapps/segnalazioni_degrado/config.
The config folder contains some properties files.
When I run my application in Development Mode (Eclipse) everything works fine, but since I deployed it on Tomcat I am getting the filenotfound exception.
This is the way I load the .properties file on the server:
[...]
Properties props = new Properties();
try {
props.load(new FileInputStream("config/DBconfig.properties"));
} catch (IOException e) {
System.out.println(e.getMessage());
}
url = props.getProperty("url");
user = props.getProperty("user");
password = props.getProperty("password");
[...]
Am I doing something wrong?

Every webapp has it's own classloader in tomcat. The ClassLoader.getSystemResourcewill use the system class loader that is used to load the bootstrap and the tomcat application. But the system class loader does not know anything about your webapp and it's classpath. Using the right class loader is essential.
There are a lot of solutions to access the correct classloader. One solution is to use ClassLoader#getResource.
Please look into this example

Am I doing something wrong?
Obviously, yes. You wouldn't be getting an exception if all was well.
You should load that resource as a stream from the classpath.
That means that your WAR should look like this:
WEB-INF/classes/config/DBconfig.properties
Since you're using Tomcat, I'd recommend learning how to set up a JNDI data source connection pool. Externalize your database connection information that way.

Related

Jetty resource base different in Maven Nested Multi-module project of IntelliJ IDEA vs Eclipse

We have a nested multi-module project. Our developers are a mix of IntelliJ IDEA and Eclipse users.
When running a jetty server inside an inner module, it seems we need to set the resource base to different values depending on which IDE we are using.
For IntelliJ:
root.setResourceBase("myModule/src/main/webapp");
For Eclipse:
root.setResourceBase("src/main/webapp");
We don't want to have to tweak our IDEs to make it work, e.g. I don't want to have to change some setting in IntelliJ to make it work with the Eclipse version of the code.
Any ideas?
The short answer:
Your execution differences between Eclipse vs Intellij can be explained by having different PWD, or ${user.dir}, or working directory setups.
The better answer:
Don't use filesystem paths then.
Look up a known resource in that location via a Classloader.getResource() and then pass the parent directory into the root.setResourceBase()
Example:
Server server = new Server(8080);
// Figure out what path to serve content from
ClassLoader cl = WebAppContextFromClasspath.class.getClassLoader();
// We look for a file, as ClassLoader.getResource() is not
// designed to look for directories (we resolve the directory later)
URL f = cl.getResource("hello.html");
if (f == null)
{
throw new RuntimeException("Unable to find resource directory");
}
// Resolve file to directory
URI webRootUri = f.toURI().resolve("./").normalize();
System.err.println("WebRoot is " + webRootUri);
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setWar(webRootUri.toASCIIString());
webapp.setParentLoaderPriority(true);
server.setHandler(webapp);
server.start();
server.join();
You can see this in the embedded-jetty-cookbook examples:
WebAppContextFromClasspath.java
ResourceHandlerFromClasspath.java
The other better answer:
Another approach is to find the src/main/webapp a few different ways depending on how it is being run
See the operational modes in the ServerMain.java in the embedded-jetty-live-war example.

access via spring injected property which references a directory to access its files

I'm trying to access a property defined in a bean like this:
<bean id="reportdepositService" class="a.b.c.ServiceImpl">
<property name="reportDeposit" value="/WebContent/WEB-INF/dirName/" />
</bean>
ServiceImpl class looks like this:
public class ServiceImpl implements IService {
private Resource springResource;
public Resource getSpringResource() {
return springResource;
}
public void setSpringResource(Resource springResource) {
this.springResource = springResource;
}
private File getSpringResourceFile() throws IOException{
Resource r = getSpringResource();
URL url = FileLocator.resolve(r.getURL());
return FileUtils.toFile(url);
}
public void doSomething(){
.. some logic .
File f = getSpringResourceFile();
}
executing that code within eclipse on a ubuntu machine works fine, application build on a jenkins works fine as well on ubuntu. Running that application on a win7/64, the code throws the following exception:
OSGi resource[/WebContent/WEB-INF/springResource/|bnd.id=332|bnd.sym=a.b.server] cannot be resolved to URL because it does not exist
java.io.FileNotFoundException: OSGi resource[/WebContent/WEB-INF/springResource/|bnd.id=332|bnd.sym=a.b.server] cannot be resolved to URL because it does not exist
at org.springframework.osgi.io.OsgiBundleResource.getURL(OsgiBundleResource.java:228)
What is necessary to access the property on windows hosted system?
Any ideas?
Thanks in advance
I am not sure whether you are on the correct road with this:
The /WebContent/WEB-INF path suggests that you are writing a web application to be run in a web container. In that case you should never assume that your resource is a file. You should open the resource using Resource.getInputStream() in stead of using the URL/File. The reason is that the the application may well be run directly from the .war without a file system being available.
That may immediately answer the question: is the Windows 7 environment the same in relation to the run-enviroment? My impression is that it is not. If you bundled the project into a bundle jar while transporting it to the windows machine, I guess you should add a prefix to the path (but probably need to leave the WebContent off), like bundle:, classpath:, etc. See Spring OSGI reference. But you need to give a little more information to be sure.

Problems with Velocity Resource Path

So, here's the deal.
I'm using Spring Framework to develop a appointment app.
Everything's going fine in my localhost, even the email send part.
But when i pass the project to my weblogic, the resource.loader.path property appears not to load.
Here's the important part of my code:
Properties prop = new Properties();
prop.setProperty("resource.loader", "class");
prop.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
prop.setProperty("class.resource.loader.path", "../jsp/email-templates");
VelocityEngine.init(prop);
Template template = VelocityEngine.getTemplate("user-response.jsp");
As i said, just the important part of my code. Basically is configured like this with a Properties Object and the VelocityEngine.getTemplate() loading the user-response.jsp file that are inside the folder mentioned above.
As i said, in my localhost, he just works fine but in weblogic appears that way:
org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '..nulluser-response.jsp'
For some reason, the class.resource.loader.path property do not load in weblogic.
So... someone has already been through this problem? Any ideias of what's wrong?
Obs.: The two projects (localhost and weblogic) are the same, using a version control software (bazaar)
I'd recommend making it relative to the CLASSPATH. If you put the /email-templates folder under WEB-INF/classes and make the load path "email-templates" it should work.

Logging in web services on weblogic

I have been trying to deploy JAX-WS services on Weblogic server as demonstrated in this link, Creating a Simple HelloWorld Web Service.
I have deployed this and found to be working perfectly fine.
Now I also want to write data to log files, whenever this service is invoked. For this I'm using log4j. This is how i tried modifying the code in the link.
package examples.webservices.hello_world;
import javax.jws.WebService;
import org.apache.log4j.Logger;
#WebService(name="HelloWorldPortType", serviceName="HelloWorldService")
public class HelloWorldImpl {
public static Logger log = Logger.getLogger(HelloWorldImpl.class);
public String sayHelloWorld(String message) {
try {
log.info("Start");
System.out.println("sayHelloWorld:" + message);
} catch (Exception ex) { ex.printStackTrace(); }
return "Here is the message: '" + message + "'";
}
}
I have set the path of log4j-1.2.8.jar file in CLASSPATH variable.
But when i try to build the web service, it errs out saying, java.lang.ClassNotFoundException: org.apache.log4j.Logger.
I'm using the same build.xml file as given in the link. Are any modifications required in build.xml file? Where should i place the log4j.properties file? Any help is appreciated.
Even if your classpath is set, this issue has to be because weblogic is not able to find log4j at runtime. To be more specific, the Classloader of the war is not able to find the log4j.
Here are the ways to troubleshoot:
Check your build.xml if you are infact bundling log4j in your WAR.
Go to the autodeploy directory, copy the war file to a different location, deflate it and check if WEB-INF/lib and check if log4j indeed exists
Check if there is more than one log4j version in your classpath.
Finally, the preferred approach for deploying set of reusable jars in weblogic is by a shared library and reference it through weblogic.xml.
It helps in:
Avoiding repetitive bundling of a jar file in different wars.
Making sure that all your deployment are streamlined to a preferred version
of a library.

Problem creating an Embedded Jetty Endpoint in a NetBeans Platform Application using System.setProperty

I created a Netbeans Platform Application using Netbeans 7.0.1 and the JDK 1.7.
I implemented my own Web Application on a normal module using Embedded Jetty 7.4.5 (consisting of a Web Service and a couple of servlets), and I created a Library Wrapper Module including all the Jetty jar files and the "jetty-j2sehttpspi-7.4.5.v20110725.jar" that I needed to be able to publish the Web Service's Endpoint. The Web module has a dependency on the Jetty module.
The code I'm using is this:
System.setProperty("com.sun.net.httpserver.HttpServerProvider",
"org.mortbay.jetty.j2sehttpspi.JettyHttpServerProvider");
server = new Server();
JettyHttpServerProvider.setServer(server);
//We read the config file
String[] configFiles = {"etc/jetty.xml"};
for(String configFile : configFiles) {
XmlConfiguration configuration =
new XmlConfiguration(new File(configFile).toURI().toURL());
configuration.configure(server);
}
// Web Services
QueryWeb qWS = new QueryWeb();
Endpoint.publish("http://0.0.0.0:" +
(server.getConnectors()[0].getPort()) + "/ws", qWS);
// Servlets
HandlerCollection hc = (HandlerCollection)server.getHandler();
ServletContextHandler sch =
new ServletContextHandler(ServletContextHandler.SESSIONS);
sch.setContextPath("/web");
sch.addServlet(stream.class, "/stream");
// We add the servlet handler to the server's context handler collection
// because it's the one used by the Web Service Endpoint
ContextHandlerCollection chc = (ContextHandlerCollection)hc.getHandlers()[0];
chc.addHandler(sch);
server.start();
When I try and run the application, I get the following error after the "Endpoint.publish" call:
Exiting C:\Program Files (x86)\NetBeans 7.0\harness\run.xml.
Exiting C:\Program Files (x86)\NetBeans 7.0\harness\run.xml.
C:\Program Files (x86)\NetBeans 7.0\harness\suite.xml:500:
The following error occurred while executing this line:
C:\Program Files (x86)\NetBeans 7.0\harness\run.xml:225:
The following error occurred while executing this line:
C:\Program Files (x86)\NetBeans 7.0\harness\run.xml:193:
The application is already running within the test user directory.
You must shut it down before trying to run it again.
As far as I understand, this is happening because the system can't find the "org.mortbay.jetty.j2sehttpspi.JettyHttpServerProvider" class. Therefore it defaults back to the web server included in the JDK, which causes a conflict since we get both web Servers (Jetty and the JDK's) trying to run on the same port (in this case it's 8081).
The only way I managed to fix this problem was by copying all the Jetty jar files into the JRE's "lib/ext" folder (copying only the "jetty-j2sehttpspi-7.4.5.v20110725.jar" results in no errors, but the server won't start). In this way the system can find the class it needs and all it's dependencies.
I suppose that what's going on is that even if NetBeans uses it's own classpath loader, the System.setProperty method is ignoring this and trying to access the standard classpath, and since a NetBeans Platform Application doesn't actually let you change the classpath directly (that would beat the whole purpose of having modules administered by the NetBeans platform), I don't really know how to make it use the library included in the wrapper module.
I can keep developing the application with the temporary solution I found, but honestly, copying stuff into the JRE folders is not an acceptable solution and will eventually result in distribution and installation problems in client machines (already tried it in a Mac OS machine and I didn't even know where the JRE kept it's libraries to try and do the same dirty trick).
Therefore I want to ask you guys if there is any solution to this particular problem or if anyone has a better explanation of what's going on and how I might fix it without having to recreate the whole architecture of my project (which actually works OK except for this little inconvenient).
Thanks in advance!
Write your question to the mailing list, dev#platform.netbeans.org, and you're more likely to get an answer.

Categories