Instantiating Oracle Driver results in InvocationTargetException - java

I have a simple web service that uses an oracle database. When I test the service internally it works fine, however, calling the web service through my client (on the same machine but in a different WAR) throws an invocationtargetexception. I've finally discovered it's an issue with instantiating the OracleDriver. It doesn't throw any exception at all so I cannot find out what the error is.
Googling has only provided a solution of using oracle.jdbc.driver.OracleDriver instead of oracle.jdbc.OracleDriver but that doesn't seem to fix anything. The jar I'm using is ojdbc14.jar and, as far as I can tell, it's included in the class path for the web service properly... since it works when I test the service with a simple main method.
EDIT:
The InvocationTargetException is generated by an AxisFault from the Axis server. The invocationtargetexception is a wrapper class, and my attempts to try to extract the exception using .getCause() always return null.
I am deploying the service using jboss and was including the driver JAR file in the library for the source but not for the server. Including the driver in /jboss/server/default/lib resolved it.

2 WARs? I suppose your ojdbc.jar is located inside WEB-INF/lib of the web service's WAR.
Maybe your WAR is inside an EAR, so you should reference the driver in MANIFEST.MF.
More info: http://java.sun.com/j2ee/verified/packaging.html

Without more information, it's hard to provide concrete suggestions; I have however had experience with an Oracle driver that attempts to connect via native OCI libraries, fails to find those libraries installed on the system, and throws an InvocationTargetException. This is all from very vague memory, so your mileage will almost certainly vary.
It's been a while, but if memory serves me, I had a case where the connection URL was incorrectly configured, and OracleDriver (or one of its wrappers) iterated through a set of possible connection methods, trying to find one that worked. In the case that the URL was correctly configured, it never got to the OCI attempt (the thin connection method attempt came first), but if the connection URL was misconfigured, the thin attempt would fail, causing the OCI attempt, which then also failed because the OCI client was not installed on the host (resulting in an InvocationTargetException.)
So, some things to check:
Is the connection URL valid? If you're using the same connection URL in both places, are you sure that both processes are binding to the same NIC? If they are binding to different NICs, it might cause connection oddities, even on the same host.
Is the environment the same in both cases - if the OCI client is getting used in your development environment, there are likely several environment variables it depends on. If those environment variables aren't set identically in the environment where the servlet container is running, I'd expect different behavior.

Related

Resource Access Exception with Spring RestTemplate onTomcat 8 (requiring proxy config) Running on Eclipse MARS

I have an application that uses spring to the calling rest services. Specifically, the RestTemplate class. Right before I make the call to:
restTemplate.execute(
url,
method,
new JSONRequestCallback(headerParams),
new JSONResponseExtractor(containerType, cls));
method, I check the value url in the call. I quite literally can copy and paste the value of that url (lets call it http://myHost.net:8081) into a browser in the same network domain as my tomcat 8 (the web container I am using in eclipse), and the service response is successfully returned from the browser. However, the execute method throws an exception upon return:
org.springframework.web.client.ResourceAccessException: I/O error: myHost.net; nested exception is java.net.UnknownHostException: myHost.net
Now, the web service I am calling is on the internet while my dev environment is not. To address, we opened an appropriate port in our firewall and I can successfully access the service endpoint from a browser (as indicated above) by properly configuring the proxy settings on the browser. Similarly, from my Tomcat 8 configuration within eclipse, I have added the following launch configuration VM arguments:
-Dhttp.proxySet=true
-Dhttp.proxyHost=myHost.net
-Dhttp.proxyPort=8080
but as I have indicated above, I still get the unknown host exception.
By the way, I did see a similar issue here (Spring RestTemplate and Proxy Auth) but that required a coding solution in the spring code. I was hoping for a configuration solution as our system will not have the proxy issue in the operational environement.
I am hoping someone might have some ideas as to either what I might be doing wrong, and/or how I might be able to better diagnose my problem. Thank you!

(In Eclipse) JDBC Database access in servlet goes awry

I'm very new to web-application programming with Java. I have two questions.
First: I have a postgresql database. I can access the database fine when doing it outside of a servlet (as a JUnit4 test). However, when I try to access it via a servlet I get:
java.sql.SQLException: No suitable driver found for jdbc:postgresql://localhost:5432/comic_store
at java.sql.DriverManager.getConnection(DriverManager.java:602)
at java.sql.DriverManager.getConnection(DriverManager.java:185)
at ilya.database.DBService.<clinit>(DBService.java:15)
at ilya.database.UserGateway.getUserByEmail(UserGateway.java:29)
at ilya.controller.Login.<init>(Login.java:12)
etc.
Why would this exception get thrown while accessing from a servlet, but not otherwise.
Second: What is the preferred way of initializing a database connection in servlets? Should I be creating a DataSource with web.xml?
Found my answer here . And Apache's JNDI Datasources HOW-TO also helped. Here's what worked: adding the driver jar to %CATALINA_HOME%/lib instead of WEB-INF/lib and then using Class.forName() to load the driver. I tried excluding Class.forName() and got the same exception. I also tried Class.forName() with the driver only in WEB-INF/lib, and that also didn't work. As I said above, I'm running Tomcat 7 and jdk 1.6.0.

Does Tomcat use cached versions of pl/sql modules?

Ok imagine this situation. I make a change to a pl/sql module, recompile it and everything is fine. No errors.
I then try to access a GUI screen on an application that runs on Tomcat. The screen calls a pl/sql module in an oracle database.
When i submit the form which should have called that pl/sql module for processing the data, i get this error
ORA-20001: ORA-06508: PL/SQL: could not find program unit being called
I checked all packages in $USER_OBJECTS and there is nothing with a status of INVALID.
I restarted Tomcat and then it starts working. Does this mean that when i recompiled the package the first time i effectively removed some cached reference to the package which Tomcat was using?
The connection to the database is via JDBC and DBCP connection pools. Does the recompile maybe invalidate the connection?
This issue is with the JDBC connection pools and is an issue you get with all app servers using JDBC connection pools, not just Tomcat. The connection pools will keep a number of connections open in the pool ready for the next request. If a PL/SQL package has been referenced by the connection and is recompiled then the next call to that package will raise an ORA-06508 error. This will affect packages anywhere in the call stack - not just the package you called directly.
To resolve this some app servers (like Weblogic) have a test method that is called periodically. If the test fails the connection is removed from the pool or refreshed in some way. I'm not sure what mechanism Tomcat has.
Another way to address it is to call dbms_session.reset_package as the first method call in your JDBC call. This will clear the package state from you're session. This approach isn't recommended as it has a performance overhead plus any package-scoped variables are reset so package initialisation blocks need to be called again - another performance hit.
If you've got the issue and you haven't got a way of dropping bad connections you'll need to reset the whole connection pool as any connection in the pool will suffer from the same exception.
The screen calls a pl/sql module in an
oracle database.
No, it doesn't. Assuming you're running a servlet based web-app on Tomcat then your browser sends a request to Tomcat, which invokes the relevant servlet and then some java class in the web-app will execute a pl/sql program as a CallableStatement.
The key to this is how the java class executes the CallableStatement and whether it retains a reference to it or prepares it each time it executes it. Can you shed any light on this?
Edit:
I beleive the Oracle JDBC driver is capable of performing statement caching, which may be causing the problem. Have a read of the driver docs to get more info.
The error you are getting usually indicates that the stored procedure/package either:
1) doesn't exist by the name you are trying to call it with (from your Java class)
2) is missing a grant EXECUTE privilege to the user (defined by the JDBC connection) that is trying to execute it
3) is missing a synonym, if it is being executed via its name only (i.e. without a schema prepended)
4) is being called without the correct number and types of parameters

JDBC in Web Service Glassfish

I have made an application with the java JDBC driver for MYSQL and that works fine. But now I'm trying to implement a web service into my application and I can't seem to get a connection made. Do I need to use a different driver or different way to connect to the MySQL server?
Thanks
You can use the same driver. Most likely you don't have your connection pool in Glassfish properly set up.
You can read about it here http://docs.sun.com/app/docs/doc/820-7692/ablih?l=en&a=view
You have to put the JDBC driver JAR either in a /lib directory that's visible to Glassfish (if it's shared) or in the WEB-INF/lib of your web service WAR.
You don't say what the error was. If it's a ClassNotFoundException, it means the class loader couldn't find the JDBC driver JAR.
If the error message is "no suitable driver found", it usually means that the syntax of your connection URL isn't correct for the given driver. The good news in that case is that the driver .class was picked up by the class loader.
Were you going to create a connection with a DriverManager, like you probably did with your app, or were you going to be ambitious and try to set up a connection pool?

Best way to access a sqlite database file in a web service

First question from me on stack overflow.
I have created a java web application containing a web service using netbeans (I hope a web application were the correct choice). I use the web application as is with no extra frameworks. This web service use a sqlite JDBC driver for accessing a sqlite database file.
My problem is that the file path end up incorrect when I try to form the JDBC connection string. Also, the working directory is different when deploying and when running JUnit tests. I read somewhere about including the file as a resource, but examples of this were nowhere to be seen.
In any case, what is the best way to open the sqlite database, both when the web service is deployed and when I test it "locally"?
I don't know much about web services, I just need it to work, so please, help me with the technicalities.
Update
To put this a litle bit in context, some "println" code gives this:
Printing the work directory from a simple JUnit test gives
C:\MinaFiler\Work\SOA\BusTimetableWS
Invoking a similar web servic method returns
C:\Program Files\sges-v3\glassfish\domains\domain1
The connection string is formed from prepending "jdbc:sqlite:" to the path which at the moment is absolute:
C:\MinaFiler\Work\SOA\BusTimetableWS\src\java\miun\bustimetable\database\sqlit\BusTimetableWS.db
However, this fails because my tests throws exceptions stating database tables doesn't exist although they really do, I can see them with sqlite3.exe .
One way would be to use a config file that you can read and fetch your connection string from there.
I'm sure the framework you are using has some kind of standard way of saving configurations.
Another option would be to place the db in a known relative path from your main execution files. Then when executed fetch your current directory, and look for the db from that path.
In any case, what is the best way to open the sqlite database, both when the web service is deployed and when I test it "locally"?
The web service should use a DataSource to retrieve a connection from a connection pool configured at the application server level. In your unit test, use whatever you want (a standalone connection pool, a direct JDBC connection).
But in both cases, why don't you use an absolute path to the database file in your jdbc url? From How to Specify Database Files:
jdbc:sqlite:C:/work/mydatabase.db
The working directory wouldn't matter if you do so.

Categories

Resources