Oracle JDBC Connexion intermittente Problème
Je suis confronté à un problème très étrange
C'est une utilisation très simple de JDBC connexion à une base de données Oracle
OS: Ubuntu
Java Version: 1.5.0_16-b02
1.6.0_17-b04
Database: Oracle 11g Release 11.1.0.6.0
Lorsque j'utilise le fichier jar
OJDBC14.jar
il se connecte à la base de données à chaque fois
Lorsque j'utilise le fichier jar
OJDBC5.jar
il se connecte, à certains moments, et à d'autres moments, il renvoie une erreur ( voir ci-dessous)
Si je recompile avec Java 6 et utilisation
OJDBC6.jar
J'obtiens les mêmes résultats que OJDBC5.jar
J'ai besoin de fonctionnalités spécifiques dans JODB5.jar qui ne sont pas disponibles dans OJDBC14.jar
Toutes les idées
Erreur
> Connecting to oracle
java.sql.SQLException: Io exception: Connection reset
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:74)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:110)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:171)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:227)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:494)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:411)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:490)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:202)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:474)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
at TestConnect.main(TestConnect.java:13)
Code
Ci-dessous est le code, je suis en utilisant
import java.io.*;
import java.sql.*;
public class TestConnect {
public static void main(String[] args) {
try {
System.out.println("Connecting to oracle");
Connection con=null;
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection(
"jdbc:oracle:thin:@172.16.48.100:1535:sample",
"JOHN",
"90009000");
System.out.println("Connected to oracle");
con.close();
System.out.println("Goodbye");
} catch(Exception e) { e.printStackTrace(); }
}
}
- Je vais avoir le même problème, est-ce résolu?
Vous devez vous connecter pour publier un commentaire.
Il y a une solution apportée à ce problème dans certains de l'OTN forums (https://kr.forums.oracle.com/forums/thread.jspa?messageID=3699989). Mais, la cause racine du problème n'est pas expliqué. Voici ma tentative d'expliquer la cause racine du problème.
L'Oracle JDBC drivers communiquer avec le serveur Oracle, de manière sécurisée. Les pilotes utilisent le java.de sécurité.SecureRandom classe pour recueillir de l'entropie pour la sécurisation de la communication. Cette classe s'appuie sur la plate-forme native de soutien pour la collecte de l'entropie.
Entropie c'est le caractère aléatoire recueillies ou produites par un système d'exploitation ou de l'application pour une utilisation en cryptographie ou d'autres utilisations qui requièrent des données aléatoires. Ce caractère aléatoire est souvent recueillies auprès de sources, soit à partir du matériel de bruits, de données audio, les mouvements de la souris ou spécialement prévu à l'aléatoire des générateurs. Le noyau rassemble l'entropie et les magasins c'est un pool d'entropie et rend le caractère aléatoire des données disponibles pour le processus de système d'exploitation ou des applications à travers les fichiers spéciaux /dev/random et /dev/urandom.
Lecture de /dev/random les drains de l'entropie avec la quantité de bits/octets, offrant un degré élevé de l'aléatoire souvent désiré dans les opérations de chiffrement. Dans le cas, si l'entropie est complètement déchargée et suffisamment d'entropie n'est pas disponible, l'opération de lecture sur /dev/random blocs jusqu'à ce que l'entropie supplémentaire est recueillie. Pour cette raison, les applications de lecture à partir de /dev/random peut bloquer pour quelques aléatoire période de temps.
Par contre, la lecture de l' /dev/urandom ne bloque pas. La lecture de /dev/urandom, trop, draine le pool d'entropie, mais, en cas de court de suffisamment d'entropie, il ne bloque pas, mais réutilise les bits de la partie lecture aléatoire des données. Ce qui est dit pour être sensibles à la cryptanalytical attaques. C'est un theorotical possibilité et par conséquent, il est déconseillé de lire à partir de /dev/urandom pour recueillir de l'aléatoire dans les opérations de chiffrement.
La java.de sécurité.SecureRandom classe, par défaut, lit à partir de la /dev/random fichier et donc parfois des blocs pour une période de temps. Maintenant, si l'opération de lecture ne retourne pas requis pour un montant de temps, le serveur Oracle fois sur le client (les pilotes jdbc, dans ce cas) et les gouttes de la communication par la fermeture de la socket à partir de sa fin. Le client lors de la tente de reprendre la communication après le retour de l'appel de blocage de la rencontre IO exception. Ce problème peut se produire de façon aléatoire sur toute plate-forme, en particulier, où l'entropie est recueillie à partir de matériel de bruits.
Comme suggéré dans le OTN forum, la solution à ce problème est de remplacer le comportement par défaut de java.de sécurité.SecureRandom classe pour utiliser le non-blocage de lire à partir de /dev/urandom au lieu du blocage de lire à partir de /dev/random. Cela peut être fait en ajoutant la propriété système suivante -Djava.de sécurité.egd=file:///dev/urandom à la JVM. Si c'est une bonne solution pour les applications comme les pilotes JDBC, il est déconseillé pour les applications qui effectuent les opérations cryptographiques de base comme crytographic la génération de clés.
D'autres solutions pourrait être d'utiliser différents aléatoire semoir implémentations disponibles pour la plate-forme, qui ne reposent pas sur le matériel des bruits pour la collecte de l'entropie. Avec cela, vous avez toujours besoin de remplacer le comportement par défaut de java.de sécurité.SecureRandom.
Augmenter le délai d'attente du socket sur le serveur Oracle peut aussi être une solution, mais les effets secondaires doivent être évalués du point de vue serveur avant de tenter cela.
J'ai été confronté exactement au même problème. Avec Windows Vista, je ne pouvais pas reproduire le problème, mais sur Ubuntu, j'ai reproduit la "réinitialisation de la connexion'-Erreur constamment.
J'ai trouvé
http://forums.oracle.com/forums/thread.jspa?threadID=941911&tstart=0&messageID=3793101
Selon un utilisateur sur ce forum:
qui a résolu mon problème.
Une "connexion réinitialisée" message d'erreur signifie généralement que l'autre côté a abandonné la connexion lors de la tentative de créer une connexion (la poignée de main). Cela a beaucoup de causes possibles. Un bogue dans le pilote JDBC, un délai d'attente auprès de la DB côté, un redémarrage de la base de données, la DB en cours d'exécution hors de connexions disponibles, la mauvaise qualité du réseau, la mauvaise virusscanner/pare-feu/proxy, etc.
Comme il arrive intermittely, d'un bogue dans le pilote JDBC peut être moins ou plus exclus. Gauche derrière le reste des causes possibles. Je suggère de commencer avec la recherche dans les logs du serveur de base de données.
C'est dur à dire, mais si je voudrais vérifier la version actuelle du pilote JDBC. Assurez-vous que c'est 11.1.0.6.
Oracle n'inclut pas la version de base de données dans le nom de fichier. Ainsi, le conducteur 11,2 est exactement le même nom que le pilote de 11.1 - ojdbc5.jar. Je voudrais extraire le fichier jar du pilote, et de trouver le MANIFESTE.MF fichier, il contient quelques informations sur la version. Assurez-vous que la version du pilote JDBC correspond à la version de votre base de données. Je soupçonne que c'est peut être un problème de version, puisqu'il n'y a pas un fichier jar nommé ojdbc14.jar sur Oracle 11.1.0.6 télécharger page.
Si la version correspond - je suis à court d'idées 🙂
Autre chose qui me causer ce problème était d'avoir la nom d'hôte paramètres mal. Ma tentative de connexion a été pendu:
Donc, assurez-vous d'avoir une entrée pour votre nom d'hôte dans
/etc/hosts/
.Si vous émettez un
hostname
de commande comme ceci:Vous avez besoin d'une ligne dans votre
/etc/hosts
:Juste pour préciser - au moins à partir de ce que nous avons trouvé à nos côtés!
C'est un problème avec la configuration de l'aléatoire pour Linux dans le JDK de distribution - et nous l'avons trouvé dans Java6, vous ne savez pas à propos de Java7.
La syntaxe pour linux pour l'aléatoire est file:///dev/urandom, mais l'entrée dans le fichier est (probablement à gauche/copié à partir de Windows) que file:/dev/urandom.
Alors Java probablement retombe sur la valeur par défaut, qui se trouve être /dev/random. Et ce qui ne fonctionne pas sur une tête de machine!!!
La cause de ce problème a à voir avec l'authentification de l'utilisateur des versions. Pour chaque base de données d'utilisateur, mot de passe multiples vérificateurs sont conservés dans la base de données. Généralement, lorsque vous mettez à niveau votre base de données, un nouveau vérificateur de mot de passe sera ajouté à la liste, un plus fort. La requête suivante affiche le vérificateur de mot de passe versions qui sont disponibles pour chaque utilisateur. Par exemple:
Lors de la mise à niveau vers une version plus récente du pilote, vous pouvez utiliser une version plus récente du vérificateur parce que le conducteur et le serveur négocient le plus fort possible verifier pour être utilisé. Cette nouvelle version du vérificateur sera plus sûr et plus impliquera de générer de plus grands nombres aléatoires ou utilisant de plus en plus complexes, les fonctions de hachage qui peut expliquer pourquoi vous voyez des problèmes, tout en établissant des connexions JDBC. Comme mentionné par d'autres réponses à l'aide
/dev/urandom
normalement résout ces problèmes. Vous pouvez également décider de déclasser votre vérificateur de mot de passe et de faire le pilote le plus récent utilisez l'ancien vérificateur de mot de passe que votre pilote précédent était de l'utiliser. Par exemple, si vous souhaitez utiliser le 10G vérificateur de mot de passe (pour les tests), vous devez d'abord assurez-vous qu'il est disponible pour votre utilisateur.Ensemble
SQLNET.ALLOWED_LOGON_VERSION_SERVER=8
dans sqlnet.ora sur le serveur. Alors:Ensuite, vous pouvez forcer le JDBC mince pilote à utiliser les 10G de vérificateur par la définition de cette JDBC propriété
oracle.jdbc.thinLogonCapability="o3"
. Si vous exécutez dans l'erreur"ORA-28040: No matching authentication protocol"
, alors cela signifie que votre serveur n'est pas en permettant à l'10G verifier pour être utilisé. Si c'est le cas, alors vous devez vérifier votre configuration.Noter que la solution proposée de l'utilisation de /dev/urandom n'a fonctionné la première fois pour moi, mais ne fonctionne pas toujours par la suite.
DBA à mon cabinet à commutation de SQL* net bannières et qu'il fixe de façon permanente, pour moi, avec ou sans ci-dessus.
Je ne sais pas quoi " SQL* net bannières sont, mais je suis en espérant en mettant cette information ici que si vous avez(sont) un DBA il(vous) savez quoi faire.
La désactivation de SQL Net Bannières nous a sauvés.
-Djava.de sécurité.egd=file:/dev/./urandom doit être bon! pas -Djava.de sécurité.egd=file:/dev/../dev/urandom ou -Djava.de sécurité.egd=file:///dev/urandom
Comme par Bug https://bugs.openjdk.java.net/browse/JDK-6202721
Java ne sera pas consder -Djava.de sécurité.egd=file:/dev/urandom
Il devrait être -Djava.de sécurité.egd=file:/dev/./urandom
OracleXETNSListener - ce service doit être démarré si elle a été désactivée.
et regarder dehors pour que les services