For school they're making us connect to a postgresDB trough plain old dao's and tomcat. However the given code ain't working and I've been stuck here for quite a bit now.
So here goes.
The connectiondao given:
package nl.hu.v1wac.firstapp.persistence;
import java.sql.Connection;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class BaseDao {
protected final Connection getConnection() {
Connection result = null;
try {
InitialContext ic = new InitialContext();
DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/PostgresDS");
result = ds.getConnection();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
return result;
}
}
We had to write the server specifics into an context.xml file, and import the jar driver into the lib folder of tomcat (so far so good). The context.xml is in the src/main/webapp/META-INF directory
The context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/PostgresDS"
url="jdbc:postgresql://localhost:5432/worlddb"
driverClassName="org.postgresql.Driver"
auth="Container"
type="javax.sql.DataSource"
username="postgres"
password="secret" />
</Context>
After setting up my Dao's, I try to fire them up in a main and get the following error:
Exception in thread "main" java.lang.RuntimeException: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
which is said caused by:
DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/PostgresDS");
Would anyone be able to help, as according the slides / manual this should be all to it :/
Thanks in advance!
p.s. we're using tomcat 8.5 and Eclipse Jee Neon
Edited Main class
package nl.hu.v1wac.firstapp.persistence;
import java.sql.SQLException;
public class Pattern {
public static void main(String[] args) {
// TODO Auto-generated method stub
CountryDao cdao = new CountryDaoPostgreSQL();
try {
cdao.findALl();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You certainly shouldn't be getting that.
You're running this code within Tomcat proper? Not outside? The complaint is that the InitialContext doesn't have the underlying "plumbing" to do the lookup. Normally this is all managed by the environment that you're running in, unless you're running it "stand alone" in a Java SE app, you should never see this.
Related
I have settings in the context.xml which contain the information for the connection of my database
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<Resource
name="jdbc/*(my username)*"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
auth="Container"
type="javax.sql.DataSource"
removeAbandoned="true"
removeAbandonedTimeout="30"
maxACtive="100"
maxIdle="30"
maxWait="10000"
username= *(my username)*
password= *(my password)*
driverClassName="com.ibm.db2.jcc.DB2Driver"
url="jdbc:db2://(my server host):50000/*(my username)*">
</Resource>
</Context>
While for the Connection Pool I created a class to initiate and to connect it to the database. The error begins in the method of getConnection(). The way the error is NullPointerException in the return of the datasource.getConnection()
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class ConnectionPool {
private static ConnectionPool pool = null;
private static DataSource dataSource = null;
private ConnectionPool() {
try {
InitialContext ic = new InitialContext();
dataSource = (DataSource) ic.lookup("java:/comp/env/jdbc/COMPANY");
System.out.print(dataSource);
} catch (NamingException e) {
System.out.println(e);
}
}
public static synchronized ConnectionPool getInstance() {
if (pool == null) {
pool = new ConnectionPool();
}
return pool;
}
public Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
System.out.println(e);
return null;
}
}
public void freeConnection(Connection c) {
try {
c.close();
} catch (SQLException e) {
System.out.println(e);
}
}
}
I tested the database connection with Eclipse's Perspective Database Development and I was able to connect and done all the queries.
In addition, it gives me this error in output
SEVERE: Unable to create initial connections of pool.
java.sql.SQLException: No suitable driver found for jdbc:db2://db2.cecsresearch.org:50000/(my username)
Although I have the jar library files in the lib folder and in the classpath.
Please download the DB2 Java driver from https://artifacts.alfresco.com/nexus/content/repositories/public/com/ibm/db2/jcc/db2jcc4/10.1/db2jcc4-10.1.jar and add it to your tomcat/lib directory. Then restart Tomcat and you should be good to go !!
The nullpointer is simply caused by the following problem:
java.sql.SQLException: No suitable driver found for jdbc:db2://db2.cecsresearch.org:50000/(my username)
Putting your database driver in $CATALINA_HOME/lib should fix the problem.
For more info, check the docs.
driverClassName (String) The fully qualified Java class name of the
JDBC driver to be used. The driver has to be accessible from the same
classloader as tomcat-jdbc.jar
You can also check the official jndi-datasource examples.
I've searched through similar questions and didn't find a solution that worked for me. I'm running following in Netbeans > servlet:
public Connection getConnection()
{
Connection result = null;
BasicDataSource dataSource = getDataSource();
try {
result = dataSource.getConnection();
} catch (SQLException ex) {
Logger.getLogger(ConnectionPool.class.getName()).log(Level.SEVERE, null, ex);
}
catch (Throwable e)
{
e.printStackTrace();
}
return result;
}
It works fine when executed in a Java project. Then I added this project's jar as a library to a servlet project in Netbeans - it throws exception:
"java.sql.SQLException: Cannot create JDBC driver of class '' for connect URL 'jdbc:mysql://127.0.0.1:3306/config'"
It looks like this "class ''" thing should point to a class name but where do I get it?
fixed that. had to put drivers into glassfish/lib directory
I have a java application running on a bluemix cloud server, I originally developed it locally on a tomcat server and then decided to migrate to the cloud. The option suggested everywhere was to use liberty and sqldb services which after some finicking I got setup on my bluemix account with the sql database named SQL-RCT bound as a service to my java application.
The problem is encountered when running the following code:
#WebServlet({ "/LoginServlet", "/" })
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Connection conn;
#Resource(lookup="jdbc/SQL-RCT")
private DataSource myDataSource;
/**
* #see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
try {
if(myDataSource == null){
throw new Exception("no data source");
}
conn = myDataSource.getConnection();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
when I try to load the servlet I get an error that there was a nullpointer exception in my init function which I quickly was able to narrow down to my myDataSource object being null.
I've checked the server.xml and I´m using the right name for the lookup but the lookup doesn't seem to work, any help would be appreciated.
the server.xml
<server>
<featureManager>
<feature>beanValidation-1.1</feature>
<feature>cdi-1.2</feature>
<feature>ejbLite-3.2</feature>
<feature>el-3.0</feature>
<feature>jaxrs-2.0</feature>
<feature>jdbc-4.1</feature>
<feature>jndi-1.0</feature>
<feature>jpa-2.1</feature>
<feature>jsf-2.2</feature>
<feature>jsonp-1.0</feature>
<feature>jsp-2.3</feature>
<feature>managedBeans-1.0</feature>
<feature>servlet-3.1</feature>
<feature>websocket-1.1</feature>
<feature>icap:managementConnector-1.0</feature>
<feature>appstate-1.0</feature>
<feature>cloudAutowiring-1.0</feature>
</featureManager>
<application name='myapp' location='myapp.war' type='war' context-root='/'/>
<cdi12 enableImplicitBeanArchives='false'/>
<httpEndpoint id='defaultHttpEndpoint' host='*' httpPort='${port}'/>
<webContainer trustHostHeaderPort='true' extractHostHeaderPort='true'/>
<include location='runtime-vars.xml'/>
<logging logDirectory='${application.log.dir}' consoleLogLevel='INFO'/>
<httpDispatcher enableWelcomePage='false'/>
<applicationMonitor dropinsEnabled='false' updateTrigger='mbean'/>
<config updateTrigger='mbean'/>
<appstate appName='myapp' markerPath='${home}/../.liberty.state'/>
<dataSource id='db2-SQL-RCT' jdbcDriverRef='db2-driver' jndiName='jdbc/SQL-RCT' statementCacheSize='30' transactional='true'>
<properties.db2.jcc id='db2-SQL-RCT-props' databaseName='${cloud.services.SQL-RCT.connection.db}' user='${cloud.services.SQL-RCT.connection.username}' password='${cloud.services.SQL-RCT.connection.password}' portNumber='${cloud.services.SQL-RCT.connection.port}' serverName='${cloud.services.SQL-RCT.connection.host}'/>
</dataSource>
<jdbcDriver id='db2-driver' libraryRef='db2-library'/>
<library id='db2-library'>
<fileset id='db2-fileset' dir='${server.config.dir}/lib' includes='db2jcc4.jar db2jcc_license_cu.jar'/>
</library>
</server>
Injected resources are not available within servlet constructors, since the resources do not get injected until after the servlet instance has been fully initialized.
Instead, override the javax.servlet.GenericServlet init() method and get your conneciton there. This lifecycle method will give you similar lifecycle behavior as how you are currently trying to create your connection in the servlet constructor.
Example code:
#WebServlet({ "/LoginServlet", "/" })
public class LoginServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
private Connection conn;
#Resource(lookup="jdbc/SQL-RCT")
private DataSource myDataSource;
#Override
public void init() throws ServletException {
super.init();
try {
conn = myDataSource.getConnection();
} catch (Exception e) {
throw new ServletException(e);
}
}
}
As a side note:
Since Liberty pools connections, it's not necessary to store a connection at the class scope. If you get connections when they are needed and close them once you are done using them, you should not see any performance difference.
If you want to get a connection in the servlet init code as a way to eagerly get a connection, that is fine, but it will impact your servlet load time.
In most containers, the naming convention for the #Resource annotation is as follows:
#Resource(name = "java:/comp/env/jdbc/SQL-RCT")
private DataSource myDataSource;
Found it on this answer:
JNDI #Resource annotation
I build webApp . When I run app from Eclipse everything work OK. Now I build WAR file, put in tomcat root, andI want to all my system property put in context.xml in tomcat. Then, when app is start, that values from context.xml is read and use in app.
Problem is I don't know how to get values from context.xml in my webapp?
This is context:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="" docBase="fileupload.war" privileged="true" antiResourceLocking="false" antiJARLocking="false">
<Resource
mail.smtp_server = "127.0.0.1"
mail.smtp_username = "no-reply#gmail.rs"
mail.mailTo = "test#gmail.com"
rootFolder = "D:/project/"
rootFolderBackup = "D:/project/Backup/"
/>
Here I want to get a values from context.xml :
#RequestMapping(value="api/files")
public class FileController {
final static Logger logger = Logger.getLogger(FileController.class);
#Autowired
ApplicationContext applicationContext;
private String mailTo;
private String sender;
private String rootFolder = "";
private String rootFolderBackup = "";
#PostConstruct
private void init(){
try {
InitialContext ic = new InitialContext();
Context xmlContext = (Context) ic.lookup("java:comp/env"); // thats everything from the context.xml and from the global configuration
DataSource myDatasource = (DataSource) xmlContext.lookup("rootFolder");
} catch (NamingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
This is common error :
Name [rootFolder] is not bound in this Context. Unable to find [rootFolder].
I try few solution which I found on web but not working...
My context.xml file is in C:\tomcat-7.0\conf\Catalina\localhost , and war file is in C:\tomcat-7.0\webapps
If you want to define application properties you should probably use Environment variables instead. Ex you can set a variable in any context.xml like this:
<Environment name="PROPERTIES_FILE" override="false" type="java.lang.String" value="C:/path/to/propfile.properties" />
<!--define more variables here -->
and then in your application you can read those environment properties from JNDI like this.
initCtx = new InitialContext();
String path = (String) initCtx.lookup("java:comp/env/PROPERTIES_FILE");
// fetch more variables here
Further reading:
https://tomcat.apache.org/tomcat-8.0-doc/config/context.html#Environment_Entries
https://tomcat.apache.org/tomcat-8.0-doc/jndi-resources-howto.html
While working on some code I got followinh error,The code and the error is as given below,Tell me if further explanations required.. ............
import java.util.Hashtable;
import javax.naming.*;
import javax.naming.directory.*;
public class OracleDataSourceRegisterJNDI {
public static void main(String[] args) {
try {
// Set up data source reference data for naming context:
// ----------------------------------------------------
// Create a class instance that implements the interface
// ConnectionPoolDataSource
OracleDataSource ds = new OracleDataSource();
ds.setDescription(
"Oracle on Sparky - Oracle Data Source");
ds.setServerName("sparky");
ds.setPortNumber(1521);
ds.setUser("scott");
ds.setPassword("test");
// Set up environment for creating initial context
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file:c:\\JDBCDataSource");
Context ctx = new InitialContext(env);
// Register the data source to JNDI naming service
ctx.bind("jdbc/ConnectSparkyOracle", ds);
} catch (Exception e) {
System.out.println(e);
return;
}
}
}
i want to use connection pooling using oracle database i am getting following error please help me out.
>
ERROR:;
javax.naming.NoInitialContextException: Cannot instantiate class: com.sun.jndi.fscontext.RefFSContextFactory [Root exception is java.lang.ClassNotFoundException: com.sun.jndi.fscontext.RefFSContextFactory]
Not sure about the code. But this is a classpath issue, you are missing the required jar from classpath. Refer: http://www.findjar.com/class/com/sun/jndi/fscontext/RefFSContextFactory.html