I am beginning to learn Web Services and I wanted to create a Simple custom one that connects to the database:
import java.sql.*;
import javax.jws.WebMethod;
import javax.jws.WebService;
#WebService
public class DatabaseService{
Connection conn;
#WebMethod
public Connection getDBConnection(){
try{
Class.forName("oracle.jdbc.driver.Oracledriver");
String url = "jdbc:oracle:thin:#localhost:1521:mysid";
conn = driverManager.getConnection(url, "myusername", "mypassword");
}catch(Exception asd){
System.out.println(asd.getMessage());
}
return conn;
}
}
I have a main Method to Call this:
import javax.xml.ws.Endpoint;
public class CallService{
public static void main(String[] args){
Endpoint.publish("http://localhost:8080/kollega_services", new DatabaseService());
System.out.println("service Started");
}
}
When I execute I get this Error:
Exception in thread "main" javax.xml.ws.WebServiceException: Unable to create JAXBContext
at com.sun.xml.internal.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:153)
at com.sun.xml.internal.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:83)
at com.sun.xml.internal.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:244)
at com.sun.tools.internal.ws.wscompile.WsgenTool.buildModel(WsgenTool.java:229)
at com.sun.tools.internal.ws.wscompile.WsgenTool.run(WsgenTool.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.tools.internal.ws.Invoker.invoke(Invoker.java:105)
at com.sun.tools.internal.ws.WsGen.main(WsGen.java:41)
Caused by: java.security.PrivilegedActionException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
this problem is related to the following location:
at java.sql.Connection
at public java.sql.Connection.webservice.jaxws.GetDBConnectionResponse._return
at webservice.jaxws.GetDBConnectionResponse
at com.sun.xml.internal.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:140)
... 10 more
Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
this problem is related to the following location:
at java.sql.Connection
at public java.sql.Connection.webservice.jaxws.GetDBConnectionResponse._return
at webservice.jaxws.GetDBConnectionResponse
at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:277)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
at com.sun.xml.internal.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:95)
at com.sun.xml.internal.ws.developer.JAXBContextFactory$1.createJAXBContext(JAXBContextFactory.java:97)
at com.sun.xml.internal.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:148)
at com.sun.xml.internal.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:140)
... 12 more
What else do I need to add to Make this work?
Related
I have a simple Java project in Eclipse, which can connect to several databases, and am trying to modify it to allow configuration of connection parameters from property file.
At current stage, I have a working DBHelper class, which provides a getDatabaseConnection() method returning a Connection item instantiated using hard coded parameters.
I am trying to create a similar class, which does the same but reads parameters from property file.
It is called PropertyParser and provides getDBConnection() method.
The fact is that Class.forName() method fails if called from this latter, even if all connection data saved in property file are exactly the same hard coded in DBHelper class, and both refer to the full class name (oracle.jdbc.driver.OracleDriver).
Here follows my code.
Old working class:
package mypath.helpers;
import java.sql.Connection;
import java.sql.DriverManager;
public class DBHelper {
public static Connection getDatabaseConnection(){
String dbClass = "oracle.jdbc.driver.OracleDriver";
String dbUrl = "jdbc:oracle:thin:#host:port/service";
String dbUser = "user";
String dbPass = "pass";
// connect to DB
try {
Class.forName(dbClass);
Connection con = DriverManager.getConnection(dbUrl, dbUser, dbPass);
con.setAutoCommit(false);
return con;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
New not working class:
package mypath.helpers;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class PropertyParser extends Properties{
// variables
private static String propFile = "conf/myprops.properties";
private static String dbClassProp = "DBCLASS";
private static String dbUrlProp = "DBURL";
private static String dbUserProp = "DBUSER";
private static String dbPassProp = "DBPASS";
// constructor
public PropertyParser() throws FileNotFoundException, IOException{
super();
this.load(new FileInputStream(propFile));
}
public Connection getDBConnection() throws SQLException, ClassNotFoundException{
// read properties
String JDBCClass = this.getProperty(dbClassProp).trim() ;
String JDBCUrl = this.getProperty(dbUrlProp).trim();
String JDBCUserId = this.getProperty(dbUserProp).trim();
String JDBCPasswd = this.getProperty(dbPassProp).trim();
Class.forName(JDBCClass);
Connection con = DriverManager.getConnection(JDBCUrl, JDBCUserId, JDBCPasswd);
con.setAutoCommit(false);
return con;
}
}
And here's the main, whith both calls:
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException, SQLException {
// this works fine
Connection con = DBHelper.getDatabaseConnection();
System.out.println("Everything works fine till now.");
// this does not work
PropertyParser pp = new PropertyParser();
Connection con2 = pp.getDBConnection();
System.out.println("I will never reach this point.");
}
And here's the output i get:
Everything works fine till now.
Exception in thread "main" java.lang.ClassNotFoundException: "oracle.jdbc.driver.OracleDriver"
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at mypath.helpers.PropertyParser.getDBConnection(PropertyParser.java:35)
at mypath.GetConnection.main(GetConnection.java:20)
ojdbc.jar file is configured in the build path of the project. Is there a way to accomplish the result?
Double quotes.
You don't have to put double quotes in properties values.
so its:
DBCLASS=oracle.jdbc.driver.OracleDriver
and not
DBCLASS="oracle.jdbc.driver.OracleDriver"
The problem is shown in the expection message:
Exception in thread "main" java.lang.ClassNotFoundException: "oracle.jdbc.driver.OracleDriver"
If I write
Class.forName("HelloWorld");
I get the following exception message:
Exception in thread "main" java.lang.ClassNotFoundException: HelloWorld
Somehow your properties file contains not the class name, but the class name enclosed in quotes.
Strip of those quotes and your code will work.
See if there is an oracle.jdbc.driver.OracleDriver class in ojdbc.jar.
In simple ways, it is an import for the class with the fully qualified name oracle.jdbc.driver.OracleDriver and see is it report an error in your eclipse.
I'm trying to connect to a MySQL database, I created the SQL database with phpmyadmin on localhost. My code seems correct and I have the JAR file added to eclipse. I have googled the error and found on here many topics that are the same but haven't been able to resolve the problem. Here is my code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
public class dbconnection {
public static void main (String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:msql://localhost:3306/g52apr","root", "");
java.sql.PreparedStatement statement = con.prepareStatement("select * from std_details");
ResultSet result = statement.executeQuery();
while (result.next()){
System.out.println(result.getString(1) + " " + result.getString(2));
}
}
}
This is the exact error:
Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:microsoft:sqlserver://localhost:3306/g52apr
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at dbconnection.main(dbconnection.java:10)
"jdbc:msql://localhost:3306/g52apr"
should be:
"jdbc:mysql://localhost:3306/g52apr"
Edited Changed SQL Server reference to MySql
I am getting the error when compiling my project-
Exception in thread "main" java.lang.StackOverflowError
at sun.reflect.Reflection.getCallerClass(Native Method)
at java.lang.ClassLoader.getCallerClassLoader(Unknown Source)
at java.lang.Class.forName(Unknown Source)
at testpackage.DriverManager.getConnection(DriverManager.java:14)
at testpackage.DriverManager.getConnection(DriverManager.java:20)
at testpackage.DriverManager.getConnection(DriverManager.java:20)
Here is my first file code-
package testpackage;
import java.sql.*;
import javax.swing.JOptionPane;
class DriverManager {
static Connection dbConnection = null;
public static Connection getConnection(String String_url, String USER, String PASS) throws SQLException
{
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
//JOptionPane.showMessageDialog(null, "driver load successfully");
} catch (ClassNotFoundException e) {
e.printStackTrace();
//JOptionPane.showMessageDialog(null, "driver load failed");
}
dbConnection = DriverManager.getConnection(String_url,USER,PASS);
return dbConnection;
}
}
I called this method in another file-
package testpackage;
import java.awt.Rectangle;
import org.openqa.selenium.firefox.FirefoxDriver;
public class testclass {
public static void main (String[] args) throws Exception
{
DriverManager Connection_getConnection = new DriverManager();
Connection_getConnection.getConnection("database string url","username","password");
}
}
Note- I have used alert to debug the issue and find function calls recursively because i am getting alert one after one.
Your DriverManager.getConnection() method consists in calling DriverManager.getConnection(), which consists in calling DriverManager.getConnnection(), ...
That's because you chose to name your class and method the same way as the standard java.sql.DriverManager.getConnection().
It looks like you're calling:
dbConnection = DriverManager.getConnection(String_url,USER,PASS);
before ever returning a value, and since that is the method you're currently in you are recursively calling this method causing an infinite loop.
The getConnection(...) method is calling the getConnection(...) method which will never end and thus the StackOverflowError
The code will end up in an infinite loop. !!! That's why the your stack get filled.!!
Fix :
Remove the
DriverManager.getConnection(String_url,USER,PASS);
called from the getConnection function will again call the same function. So remove that from getConnection function
Your call
dbConnection = DriverManager.getConnection(String_url,USER,PASS);
creates an endless recursion. You are importing java.sql.* but nonetheless your call calls getConnection() in your class.
Change to
dbConnection = java.sql.DriverManager.getConnection(String_url,USER,PASS);
I am Using a method in a session bean that is surrounded by a try and catch bloc with an IOException and it looks like it is making a problem as when i try to call a method from a java project client so here is my bean code
package com.et;
import com.gestionfichier.gestion.*;
import java.io.IOException;
import javax.ejb.ApplicationException;
import javax.ejb.Stateless;
#Stateless
public class PremierEJB3Bean implements PremierEJB3 {
public String envoicode(String Code) {
String s = null;
try {
s = GestionFichier.CopierCode(Code);
} catch (IOException e) {
e.printStackTrace();
}
CompilerFichierC.CompilerFichier(s,s);
return "Compilation réussie !";
}
}
and here is my client bean code:
package com.et;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class PremierEJB3Client {
public static void main(String[] args) {
try {
Context context = new InitialContext();
PremierEJB3 beanRemote = (PremierEJB3)
context.lookup("PremierEJB3Bean/remote");
System.out.println(beanRemote.envoicode("somthing"));
} catch (NamingException e) {
e.printStackTrace();
}
}
}
and here is what i get in the console
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at $Proxy0.envoicode(Unknown Source)
at com.et.PremierEJB3Client.main(PremierEJB3Client.java:15)
Caused by: java.lang.ClassNotFoundException: [Ljava.lang.StackTraceElement;
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
And more....
so i am quiet sure that exceptions in my bean are causing me this problem but i have no idea how to fix that
In order to do JNDI lookup for the EJB from a standalone client, context properties needs to be added.
Something similar to below.
Hashtable<String, String> ht = new Hashtable<String, String>();
ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
Context ct=new InitialContext(ht);
This doesn't necessarily indicate that the EJB bean is not found - a possible case would be that the bean is found, and its initializer is called in the EJB container, and an exception is caused there.
Thus you might see ClassNotFound - java.lang.StackTraceElement because somehow a serialized StackTraceElement is returned back to the client which cannot be de-serialized (e.g. because of an incompatibility between the Java version used to compile the code in the server and the code in the client?)
This was happening in my own scenario, where the EJB was found, but later when I called some method on it, a similar stack trace was appearing - because of an exception happening on the EJB container/server side. I fixed the error in the EJB and stopped looking for the reason its stack trace cannot be passed safely to the client.
when i run the following :
package NonServletFiles;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.sql.DataSource;
import javax.naming.*;
public class GetTagsFromDatabase {
public GetTagsFromDatabase() {
}
public String[] getTags() {
String tags[] = null;
try {
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/photog"); // <<----- line 23
Connection connection = ds.getConnection();
String sqlQuery = "select NAMEOFTHETAG from tagcollection";
PreparedStatement statement = connection.prepareStatement(sqlQuery);
ResultSet set = statement.executeQuery();
int i = 0;
while(set.next()) {
tags[i] = set.getString("NameOfTheTag");
System.out.println(tags[i]);
i++;
}
}catch(Exception exc) {
exc.printStackTrace();
}
return tags;
}
public static void main(String args[]) {
new GetTagsFromDatabase().getTags(); // <<----- line 43
}
}
I get the following exceptions :
javax.naming.NamingException: Lookup failed for 'java:comp/env/jdbc/photog' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.url.pkgs=com.sun.enterprise.naming, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} [Root exception is javax.naming.NamingException: Invocation exception: Got null ComponentInvocation ]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at NonServletFiles.GetTagsFromDatabase.getTags(GetTagsFromDatabase.java:23)
at NonServletFiles.GetTagsFromDatabase.main(GetTagsFromDatabase.java:43)
Caused by: javax.naming.NamingException: Invocation exception: Got null ComponentInvocation
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.getComponentId(GlassfishNamingManagerImpl.java:873)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:742)
at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:172)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:498)
... 4 more
I don't know the reason for this exception,all other servlets that need to connect to the database with the url java:comp/env/jdbc/photog work fine.
The stacktrace hints that you're using Glassfish. Remove the java:comp/env/ part. It's the default JNDI context root already. Only in Tomcat you need to specify it explicitly. Also, you should be invoking this in webapp context, not as a plain Java Application with main().
Unrelated to the concrete problem, do you really need to get the DataSource everytime? I'd create a helper class which obtains it only once on webapp's startup or in a static initializer. It's application wide and threadsafe. Only the Connection indeed needs to be obtained (and closed! you're not closing it, so you're leaking DB resources) everytime you need to fire a SQL query.