tomcat6 sqlnet encryption failure - java

Recently inherited an old Java codebase that makes use of tomcat6 with apache and am attempting to set up a dev environment. I'm getting an ORA-12649 code ("Unknown Encryption or Data Integrity algorithm") when calling DriverManager.getConnection() via the front-end JSP logon screen.
There are a number of things that do not make sense:
we have implemented encryption (via settings in slqnet.ora) on the target db which runs Oracle 11gR2, and it works with the production version of the same codebase; it also works with incoming sqldeveloper connections, etc.; basically, there have been no problems with the encryption implementation on the db side
the development codebase is exactly the same as the production codebase (at this point in time)
the development tomcat6 installation is the same version as the production installation
if I point the connector at another db that does NOT implement encryption, the authorization succeeds with a valid username and password
After extensive reading through Oracle documentation and forums, tomcat6 documentation (specifically the convoluted way it handles the CLASSPATH variable) I have come up empty.
My hunch is that the tomcat6 install on the dev system is not referencing the correct jar files even though I have the ojdbc6.jar file in the tomcat install lib folder. According to Oracle, having ojdbc6.jar available should just work when it comes to implementing this type of encryption from a thin client, which is how this tomcat app is implemented.
Here's how encryption is being implemented on the client side; this compiles without error:
...
prop.setProperty(
OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL,
AnoServices.ANO_REQUIRED);
prop.setProperty(
OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES,
"( " + AnoServices.ENCRYPTION_AES256 + "," +
AnoServices.ENCRYPTION_3DES168 + "," +
AnoServices.ENCRYPTION_AES192 + " )");
// require the use of the SHA1 algorithm for data integrity checking
prop.setProperty(
OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL,
AnoServices.ANO_REQUIRED);
prop.setProperty(
OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES,
"( " + AnoServices.CHECKSUM_SHA1 + " )");
...
Here are the pertinent lines in the sqlnet.ora file on the db side, which is known to work with multiple clients:
SQLNET.ENCRYPTION_SERVER=required
SQLNET.ENCRYPTION_TYPES_SERVER=(AES256,AES192,3DES168)
sqlnet.crypto_checksum_server=required
sqlnet.crypto_checksum_types_server=(SHA1)
This is the db url being used in tomcat's web.xml file in the application directory:
jdbc:oracle:thin:#<my_db_name>:1521:<my_db_sid>
My context.xml file implements the 'allowLinking' feature, not sure if that makes a difference but it is non-standard so I'm including that detail. This allows me to provide a symlink in tomcat's <webapps> folder that points to the proper location in my repo. The directory permissions are OK since tomcat is serving up pages from that location.
<Context path="/<my_app_name>" allowLinking="true">

It seems that the ojdbc6.jar file referenced in the CLASSPATH during servlet compilation was different than the ojdbc6.jar file referenced by tomcat6. My working assumption was that contents of any file named "ojdbc6.jar" is static, but apparently I was wrong! (Can anyone confirm if Oracle does indeed release different versions of the file named "ojdbc6.jar"? I couldn't find any evidence that they do).
After much more time spent on this, I became convinced that the issue lay in the driver version being used even though the jar filename was "ojdbc6.jar" across all instances. So, I used md5sum to confirm that both .jar files were the same, and sure enough, they were not! So I re-downloaded ojdbc6.jar from Oracle and copied it to both locations where it was needed, recompiled my servlet classes, and restarted tomcat6. No more errors on login over the encrypted connection.
So it appears that someone had the grand idea of renaming an older/invalid version of an ojdbcX.jar file to ojdbc6.jar in the past. I don't even want to know why. :)

Related

"jar:file" vs. only "file:" reference when retrieving resources in Java

This question is related to my question
Jetty 11.0.11 - 404 on html file in \src\main\webapp\static - maven embedded fat jar
What --EXACTLY-- does "jar:file" mean as a Java resource reference, vs. just "file:"?
And how is that influenced by the operating system ran under?
E. g. using this resource reference in Jetty webserver, in Windows with Oracle JDK 17, files are found as resources and parsed by Jetty webserver:
file:///D:/Projects/verdi_2/target/classes/static/,AVAILABLE}{file:/D:/Projects/verdi_2/target/classes/static}
Using this resource reference in Jetty webserver, in Ubuntu Linux 20.04 LTS with Oracle JDK 17, NO files are found and nothing can be parsed by Jetty webserver:
jar:file:/usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static
Is there a difference in how a Linux version of JDK interprets "jar:file" vs. how a Windows version of the JDK interprets "jar:file"?
EDIT: The related issue is the Jetty webserver apparently can no longer serve resources directly out of a JAR file it is itself embedded in. This is now a GitHub bug ticket at https://github.com/eclipse/jetty.project/issues/8549
file: is the beginning of a general file url. jar:file: is that for a jar file particularly, with a view to referring (usually) to a particular entry in a jar. Here's an example you can run (obviously with your own jar url) where you can save an entry as a file (given by the parameter to the app)
import java.nio.file.Paths;
import java.nio.file.Files;
import java.net.URL;
public class JarUrl {
public static void main(String[] args) {
try {
URL url = new URL("jar:file:root.jar!/root/a/b.txt");
Files.copy(url.openStream(), Paths.get(args[0]));
}
catch(Throwable t) {
t.printStackTrace();
}
}
}
What --EXACTLY-- does "jar:file" mean as a Java resource reference, vs. just "file:"?
You're mischaracterising the URL a little bit. The string until the first : decides the 'scheme' of a URL, so, the pertinent question is: How does jar: work. The file: part is a smaller aspect of a sub-part of the jar bit.
How does jar: work
The format is jar:(URL-of-jar)!(path-inside-jar)
Where URL-of-jar is itself a valid URL (and file: is just one way to do that. So is http, for that matter), and path-inside-jar is not a URL but a path.
The meaning is: First, resolve the 'URL-of-jar' URL. This gets you a jar file. Then, open the jar file, and retrieve the resource at the stated path.
So, to pull this one apart:
jar:file:/usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static
The jar is located at URL file:/usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar and the resource it is referring to is the /static resource inside the jar found at the given URL.
How does file: work
That's not java-specific; file: is a generally available URL scheme. You can even type it in a web browser. The more general URL formatting scheme is scheme://server/resource, but with file:, server doesn't apply (it is by definition local to the system you are on), so usually its put as file:///foo, i.e. - an empty 'server' part. Because 3 slashes is a drag to type, I guess, file:/resource is allowed by some 'URL parsers', including java's in this regard, so, file:/usr/... simply maps straight to a local folder: /usr/src/verdi/verdi-12-JDK-etc, as in, if you type ls /usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar on the command line on your system, it would show a result (and if it does not, this URL would fail to find anything).
And how is that influenced by the operating system ran under?
It isn't. file URLs are a general concept that work on any platform. Of course, /usr/src/verdi/etc is never going to work correctly on a windows platform. Or on anybody else's machine. The problem isn't "Oh no! This won't run on another OS!". The problem with file URLs, especially absolute ones, is "Oh no! This will not run on any machine other than this one!".
file:///D:/Projects
I've explained the triple slashes earlier. This is the standard windows 'scheme' for how to stick paths in file URLs: Always forward slashes (even though windows normally uses backslashes), and treat the disk letter as if it is a 'drive' in the 'root': /D:/Project is URL-ese for:
D:
cd \Project
There is no difference in OS at all - file: URLs are handled by 'interpret this file URL the way any file URL would be interpreted on this machine'.
The answer to the related question
Jetty 11.0.11 - 404 on html file in \src\main\webapp\static - maven embedded fat jar
which prompted this post is in the long series of posts beneath this GitHub issue for jetty:
https://github.com/eclipse/jetty.project/issues/8549
In essence, eventually I had to first clean up my Maven pom.xml (see this thread for the discussion and for links to a pom.xml example that is compliant with Maven Shade plugin and Jetty 11.0.11 requirements and standards) then at the end of the day hardcode a link to the JAR file to find the HTML, JS, etc. resources Jetty was to serve out as a webpage. Also put in a conditional where, on compiling, I need to specify if the code will run "in-IDE" (in my case, Netbeans 14) or "in-JAR" - e. g. in a detached JRE elsewhere than the Netbeans 14 IDE.
Also dropped using the Jetty WebAppContext class and started rendering web content out of a normal ServletContextHandler.
Hopefully this may help someone upgrading Jetty from Jetty 9.xxx to 11 and finding that it all falls apart.
For details as to why they changed so much, see the GitHub link (the last few entries are apropos.)
The github discussion also contains full working source code (startJettyc method) that solved the issue of getting a 404 in a detached, non-IDE modality where the JAR was being run in an JRE separate from an IDE.
Stefan

Derby DB installed, JAR included, where to locate DB for portability of project?

So I'm new to working with Java databases and I've settled on using Apache Derby. I have it installed on my system and have included the derby.jar in the project buildpath. However, I need this project to be portable (including from Windows to OSX/UNIX) so that the database can be initialized and fully accessed for updating and reading on a device other than my machine.
So my question is, how do I make this happen? Is including the derby.jar file enough or do I need to do something like initialize a database within the project file system or something else? Do I need to specify a certain write location in a class within the project? If it's helpful, I'm using Eclipse IDE.
Thanks for any help!
So after some thorough reading I found my own solution, at least in theory (I've not yet finished the project build to try it out). Use this in a Data Access Object (DAO).
As per John O'Conner:
private void setDBSystemDir() {
/* Decide on the db system directory: <userhome>/DerbyDB/DBName/ */
String userHomeDir = System.getProperty("user.home", ".");
String systemDir = userHomeDir + "/DerbyDB/DBName";
// Set the db system directory.
System.setProperty("derby.system.home", systemDir);
}

JNLP loads Sigar native libs via file: but not http:

I have an app that is using jnlp as the launcher. It uses the Sigar libraries which require dynamically loaded native libraries for platform specific code.
For purposes of debugging this I have two JNLP files, one that references the codebase using file: urls and the other using http: urls. The http urls point to localhost apache which is properly serving the files. I can watch JNLP download them during its launch sequence via apache logs so I know the files are getting to my app properly.
Here are the two codebase tags
codebase="file:/Users/siberian/Documents/workspace_mnis/MNIS/localhost/"
href="file:/Users/siberian/Documents/workspace_mnis/MNIS/localhost/minis.jnlp"-->
and
codebase="http://localhost/"
href="http://localhost/mnis.jnlp"
If I double click the file: version it works fine. If I load it via my browser it works fine.
If I double click or browser load the http: version it fails to find the dynamic libraries with this error:
JNLPClassLoader: Finding library liblibsigar-universal64-macosx.dylib.dylib
[AWT-EventQueue-0] DEBUG Sigar - no libsigar-universal64-macosx.dylib in java.library.path
org.hyperic.sigar.SigarException: no libsigar-universal64-macosx.dylib in java.library.path
Now, the interesting to note is that file that it says it cant find
liblibsigar-universal64-macosx.dylib.dylib
Note the prefix extra 'lib' and postfix extra '.dylib'.
There are notes on the Sigar/vmware forums about similar problems with no solutions.
The core question is, why is this acting differently in a file: context vs an http: context?
Also of note, I have unsigned and resigned all of my files, there are no signature errors that I can see.
There are hints at an answer here: Java Webstart with Tibco Native Libs
But it works in a file: context which makes me think something else is wrong.
Also: JaNeLa tells me all is fine
JNLP and Sigar classloaders do not play well together. This was pieced together but works well in both Windows and Mac environments. The VMWare forums HINT at an answer like this but no one has put it all together. For JNLP you need to specifically do a loadLibrary based on your architecture. In a non-JNLP context Sigar handles this transparently but JNLP breaks that somehow, requiring this manual platform selection.
Just put this method into your class and call it BEFORE you call new Sigar() and it should work properly. This solutions requires the commons-lang library. You can easily extend this for linux and other alternate platform support.
private static void preloadSigar() {
String arch = System.getProperty("os.arch");
String libName;
if (SystemUtils.IS_OS_WINDOWS) {
if (arch.equalsIgnoreCase("x86"))
libName = "sigar-x86-winnt";
else
libName = "sigar-amd64-winnt";
} else if (SystemUtils.IS_OS_MAC_OSX) {
if (arch.startsWith("i") && arch.endsWith("86"))
libName = "sigar-universal-macosx";
else
libName = "sigar-universal64-macosx";
} else {
throw new RuntimeException("Unrecognized platform!");
}
System.setProperty("org.hyperic.sigar.path", "-");
System.loadLibrary(libName);
}

An issue when trying to launch and deploy Jetty

I have an issue whenever I am trying to deploy Jetty on a specific machine (works with others), the machine is a non-English Windows machine.
[2013-02-15 04:14:05.894] [ERROR] Thread-39
System.err
java.lang.IllegalStateException: Cannot create tmp dir in
C:\Windows\system32\config\systemprofile\AppData\Local\Temp\ for
context o.e.j.w.WebAppContext{/spdy,null},C:\Program
Files\server\work\tmp\my-app\webapps\spdy.war
[2013-02-15 04:14:05.894] [ERROR] Thread-39
System.err
java.io.IOException: Žw’肳‚ꂽƒpƒX‚ªŒ©‚‚©‚è‚Ü‚¹‚ñB
I tried to see if this is an issue related to admin rights but it is not, I am launching the process with admin rights.
Any suggestions are really appreciated.
Thanks!
Was able to find the issue out. Jetty does not create the TEMP folder if it doesn't exist so you have to check yourself and create the temp folder if it is not there.
In this instance, it ended up being that:
C:\Windows\system32\config\systemprofile\AppData\Local\Temp\ does not exist although C:\Windows\system32\config\systemprofile\AppData\Local\ does and TEMP=C:\Windows\system32\config\systemprofile\AppData\Local\Temp\
Creating "Temp" directory in C:\Windows\system32\config\systemprofile\AppData\Local\ solved the issue!
This is pretty old post, but recently I had just the same problem, so I want to share my experience too.
Parts of the code causing the problem can be found here:
http://download.eclipse.org/jetty/stable-8/xref/org/eclipse/jetty/webapp/WebInfConfiguration.html#225, resolveTempDirectory (WebAppContext context) method (check last lines of the method, third case explained in the comments). So, another workaround for the problem can be also changing default java.io.tmpdir folder to point to an existing one.
I have already checked on some systems and C:\Windows\system32\config\systemprofile\AppData\Local\Temp folder doesn't exist on Windows: 7, 2008, 2012.

Tomcat error: java.sql.SQLException: No suitable driver found for jdbc:sqlserver://

I have a terrible problem with Tomcat, well terrible because of this problem I've thrown away the project for more than a month now... Yet I'll still need to solve it and to go on with the project...
So it's throwing me this error:
java.sql.SQLException: No suitable driver found for jdbc:sqlserver://isd.ktu.lt:1433;DatabaseName=LN2012_bakDB2
java.lang.NullPointerException
The thing is that the same application is working in the desktop version perfectlz, however when it comes to the version which is supposed to be running on the server (Tomcat 7.0.22.0 inside NetBeans 7.1.2) it just throws the Error. It seems it doesn't load the pooling driver or I don't even know...
Well here's the part responsible for that:
public DatabaseConnection(Parameters params) {
// parameters and the output
this.gui = params.getGui();
// activate database pool
connectionPool = new GenericObjectPool(null);
connectionFactory = new DriverManagerConnectionFactory(params.getDbAdr(), params.getDbUser(), params.getDbPass());
poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, connectionPool, null, null, false, true);
driver = new PoolingDriver();
driver.registerPool("GenTreeDatabase", connectionPool);
//driver.registerPool("jdbc:apache:commons:dbcp:GenTreeDatabase", connectionPool);
}
public void openConn() {
if (allowOutput) gui.print("Getting connection to database");
try {
con = DriverManager.getConnection("jdbc:apache:commons:dbcp:GenTreeDatabase");
if (con != null) {
if (allowOutput) gui.print("Connection to database was successful");
}
} catch (SQLException ex) {
gui.err(specificError + "Error getting connection to database - " + ex);
}
}
It happens at the point where it tries to get the connection, then it gets a null pointer exception, since the connection is not retrieved successfuly.
I'm not familiar with Tomcat and up until this moment, Netbeans handled tomcat fine...
The thing is I hate errors like this... If you don't solve it in three days, you get so frustrated and don't wanna get back to that, you feel like hitting a wall...
Now I tried googling a lot about it, but still it wasn't much of a help...
So I'd be really glad if somebody could help me with this. Thanks. :)
You have to copy the JDBC Driver's jar into $CATALINA_HOME/lib.
This is probably too late to answer this question but in order to help with similar issues, Here's how I got around it.
Quick Solution:
Copy the JDBC-driver JAR file (mine was ojdbc6) into $JAVA_HOME/jre/lib/ext (for me it was C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext).
Details:
According to Apache Tomcat 7 documentations When Tomcat is started, it creates a set of class-loaders that are organized into the following parent-child relationships:
Bootstrap
|
System
|
Common
/ \
Webapp1 Webapp2 ...
Each class loader, searches for JAR files inside a certain directory. The classes and resources that they make visible are explained below:
Bootstrap : This class loader contains the basic runtime classes provided by the JVM, plus any classes from JAR files present in the System Extensions directory $JAVA_HOME/jre/lib/ext.
System : This class loader is normally initialized from the contents of the CLASSPATH environment variable. All such classes are visible to both Tomcat internal classes, and to web applications. However, There are some exceptions for Tomcat.
Common : This class loader contains additional classes that are made visible to both Tomcat internal classes and to all web applications. This class loader looks (by default) in $CATALINA_BASE/lib and $CATALINA_Home/lib for jar files.
Webapps : A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.
In conclusion, buy putting the ojdbc JAR file inside $JAVA_HOME/jre/lib/ext the JDBC driver, will get visible at the Bootstrap level.
I too encountered the same issue. It is because your tomcat server does not have the jar file of your JDBC. I fixed the problem by copying the JAR file to lib folder in tomcat server.
it helped me copying the mssql-jdbc-9.2.1.jre8.jar file to the C: \ Java \ jdk1.8.0_291 \ jre \ lib \ ext folder

Categories

Resources