Lately, I have been working with Oracle ADF Faces for some time. Despite some features missing in JDeveleoper when compared to popular Java IDEs like Eclipse or IntelliJ Idea, the development went quite smoothly. I have jumped into an “almost-done” project to resolve some of its issues. One of the issue was that users were not able to change the password in Oracle database using the application, nor was the application able to detect expired passwords. After I have done some Google investigation, I have found that:
- it is not possible to do password change using JDBC Thin driver, one has to use OCI driver instead;
- OCI drivers use native libraries and require Oracle client installed.
Great! I had Oracle XE installed on my laptop and at least I thought I knew what to do and I expected a transition to OCI driver to be as simple as replacing the thin in the connection string by oci8. Well, it wasn’t that easy. There were couple of other things that had to be done each one leading to another JBO error, UnsatisfiedLinkError, SQLException or some other kind of monster. While there are many discussions on the web, especially in Oracle forums, I have not found them complete enough so I decided to make you guys life a little easier by learning from my mistakes ;).
So here is checklist I recommend you to check before you try to pull your hear from head in a total despair:
Assure that you have Oracle client correctly installed on your computer
Check whether you have Oracle client correctly installed and the PATH variable is correctly set to include Oracle folder with DLL files. That is, for Windows machines, you should have
ORACLE_HOME\bin in your
PATH variable, on Unix / Solaris systems your
LD_LIBRARY_PATH should include
ORACLE_HOME/lib and also
ORACLE_HOME/lib32 in case you are running 32-bit JVM against 64-bit Oracle database. I recommend you to check the system variables using this guide.
Check your application server / JDeveloper embedded server libraries
Well, if you simply use JDeveloper embedded server and you are getting UnsatisfiedLinkErrors like this:
at oracle.jdbc.driver.T2CConnection.t2cGetCharSet(Native Method)
at oracle.jdbc.driver.T2CConnection.getCharSetIds( T2CConnection.java:2801)
at oracle.jdbc.driver.PhysicalConnection.<init>( PhysicalConnection.java:344)
at oracle.jdbc.driver.T2CDriverExtension.getConnection( T2CDriverExtension.java:79)
most probably you do not have the right
jdbc/lib directory inside JDeveloper home directory. These jar files have to match the version of native libraries of your Oracle client. Replace them with jar files contained in your Oracle client’s
jdbc/lib directory and you should be fine. It might happen, however, that you won’t get rid of this exception as it happend also to me. Then you have to check the libraries on your classpath. Most probably you have some kind of additional incorrect
ojdbc14dms.jar or even
ojdbc14_g.jar set in JDeveloper’s libraries settings – check both Model and ViewController and get rid of them. The point is that you might have some bad jar file on your classpath that overrides correct jars inside
To deploy the application inside third-party application server or servlet container (such as Tomcat), it should be enough to include the correct
ojdbc14_g.jar files in your WAR archive’s
WEB-INF/lib (this won’t work in case you want to deploy multiple applications that use OCI driver, because of Java Virtual Machine’s inability to load the same native libraries in different class loaders – in that case you should put
ojdbc14_g.jar files inside
shared/lib folder of Tomcat instead. This might have some additional issues, I will write about that in some of the future posts, hopefully :) ).
Check your connection strings
So you have double-checked all the settings and still getting some kind of error like ORA-12154: TNS:could not resolve the connect identifier specified. It even might happen that on some environments it might work, while keeping returning this error on the others — with almost the same settings in your tnsnames.ora file. Yes, the error could mean that your
ORACLE_HOME/network/admin/tnsnames.ora is wrong or could not be found. So anyway, check whether the file is correct and environment paths and permissions are set correctly. You can check it by using
sqlplus client to connect to the specified service. However, if
sqlplus connects flawlessly, there might be an error in connection string used in your application.
The application I have been working on, used the following connection string:
XE here is name of the service as it can be defined in tnsnames.ora file. While this worked well on my laptop and on development environment that used HP-UX system with Oracle 10.1.0 installed, it didn’t work on another HP-UX system (testing environment) with Oracle 10.1.0 database. After I have checked all the settings multiple times, I have found that the correct OCI8 connection string should look like this:
SERVICE_NAME string with service name you want to use and… voila! In my case it finally worked on all environments.
As I mentioned above, this checklist does not include some other issues you might run into when trying to deploy mutliple applications using OCI driver under the same application server. But it should help you in case you want to simply run a single web application. Good luck!