I'm working on a web application using netbeans and MS Acces as my database, in my connection class I tried to get the path of my acces file (located inside my project) via the following command:
File f = new File("softTech.accdb");
String path = f.getAbsolutePath();
The problem is, as soon as I run the project and it tries to connect, when trying to get the path, the system gives me a path inside the tomcat's paste
I need your help, don't know what to do
Thanks in advance
There are two points:
First: MS Access is really the worst choice as a database for a Java web application.
MS Access is a desktop database not made for using it at the server side.
The JDBC-ODBC bridge was never meant for production use and was removed in Java 8.
The alternate driver Ucanaccess is nice for data exchange scenarios with a MS Access database but it uses a pure Java database (HSQLDB) as a buffer and an emulation layer to avoid the use of the original Jet Engine. This alone is a performance nightmare.
So you should consider to use another database for your web application. There are plenty of alternatives like SQLite, Apache Derby or H2 as embedded database engines or MySQL, PostgreSQL as client-server database systems. All with dedicated JDBC driver support.
Second: The database path or the connection shouldn't be hardcoded inside your web application. You should configure a named datasource in your application server (e.g. Tomcat). And inside your web application you can access the datasource via JNDI.
Example: Configure the database connection factory in Tomcat:
<Context ...>
...
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="dbusername"
password="dbpassword"
driverClassName="org.hsql.jdbcDriver"
url="jdbc:HypersonicSQL:database"
maxActive="8"
maxIdle="4"/>
...
</Context>
Example: Access the datasource via JNDI:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
The examples are part of the Tomcat documentation.
The benifit is, the web application only knows the logical database name. You can have multiple Tomcat installation, e.g. one for testing with a test database and one production. You can use the same WAR file for both installations. Each Tomcat has to be configured only once.
If you are using servlets then following code should work.
getServletContext().getRealPath("/yourFileName")
In case of normal java class, you can use
new File("yourFileName").getCanonicalPath();
Related
I am learning Java EE. My instructor told me to implement JNDI DataSource in my learning project. I have found some articles on the subject but I can't see clearly the steps to doing this.
My training project is a Spring MVC application. On the front end it has some Thymeleaf templates, and the data are taken from a PostgreSQL database.
What should be done to implement JNDI here? I don't even know why I need it. I was only told that this configuration should be considered obsolete and low-level, but I have no idea why.
Now the database is configured as follows:
a props file with the following content:
driver=org.postgresql.Driver
url=jdbc:postgresql://localhost/trainingproject
dbuser=postgres
dbpassword=Password
a .sql file which looks like this:
DROP TABLE IF EXISTS table1;
CREATE TABLE table1
(
row1 SERIAL PRIMARY KEY,
row2 CHARACTER VARYING(64)
);
a DataSource bean:
#Bean
public DataSource datasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getProperty(DRIVER));
dataSource.setUrl(environment.getProperty(URL));
dataSource.setUsername(environment.getProperty(USER));
dataSource.setPassword(environment.getProperty(PASSWORD));
}
PGSimpleDataSource implementation of DataSource is bundled with JDBC driver.
The JDBC driver for Postgres at https://jdbc.postgresql.org includes an implementation of DataSource: PGSimpleDataSource
PGSimpleDataSource ds = new PGSimpleDataSource() ;
ds.setServerName( "localhost" );
ds.setDatabaseName( "your_db_name_here" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
For more info:
The Javadoc for DataSource.
The Javadoc PGSimpleDataSource.
My Answer to the Question, Produce a DataSource object for Postgres JDBC, programmatically
The JDBC driver’s manual.
JNDI
Your question conflates two issues: DataSource and JNDI.
A DataSource is a simple object holding all the connection info needed to make a connection to a database. This includes a username, a password, the address of the database server, and any number of standard and proprietary feature settings. By proprietary, I mean Postgres-specific feature settings versus Microsoft SQL Server-specific versus Oracle-specific, etc. Look at the Javadoc for DataSource to see how simple it is, basically just a getConnection method. You can obtain a DataSource object with or without JNDI; the two are orthogonal issues.
JNDI is much more complex. JNDI is an interface for obtaining from a naming/directory server the configuration info needed by your app at runtime. Using this interface to such a server means you need not include deployment details in your codebase; you look up needed details on-the-fly at runtime.
Database connection info is but one of many kinds of info you might want to obtain from a JNDI server. You might also look up web services servers, logging services, and so on.
So rather than hard-coding your database connection info, you might want to “discover” the proper database connection info when launching your app. Your testing machines will use a bogus database server while your production deployment machines will use a different database server. These database servers may not be known to the programmer at compile time, or may not even exist yet. A look-up needs to be done, and JNDI is a standard way to do so without vendor lock-in.
How you configure database connection info to be delivered by a JNDI-compliant naming/directory server as a DataSource object to your app differs wildly depending on the particular server environment of your enterprise. Given your last code example, it looks like you are not actually accessing a JNDI server in your class, so JNDI is moot.
My WAR application is deployed to Amazon Elastic Beanstalk. They don't support JNDI, but I need it for JPA and unit tests. What JNDI context factory I can use as a workaround? I need a simple open source solution, that would allow me to configure entire factory through jndi.properties. I tried GuiceyFruit, but looks like it doesn't allow data source configuration inside one file. Any suggestions?
ps. OpenEJB will work, but it's an overkill for such a simple task
Try Simple-JNDI. It gives you an in-memory implementation of a JNDI Service and allows you to populate the JNDI environment with objects defined in property files. There is also support for loading datasources or connection pools configured in a file.
To get a connection pool you have to create a file like this:
type=javax.sql.DataSource
driver=com.sybase.jdbc3.jdbc.SybDriver
pool=myDataSource
url=jdbc:sybase:Tds:servername:5000
user=user
password=password
In your application you can access the pool via
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("path/to/your/connectionPool");
You can find more about it at https://github.com/h-thurow/Simple-JNDI.
I have some code that I want to make public. The code sends email via servers, connects to databases, and other tasks requiring usernames/passwords.
I'd like to store the passwords and such in a seperate configuration file so that I don't have to sanitize my code on every commit.
How can I do this? It would be easy to do in C using #define, but I'm not sure how to accomplish this in Java.
EDIT: The environment I'm using is Glassfish
The basic method is put the information in a properties file and use the Properties class to load it at run time. If you're using a J2EE server, database connections are configured in the server and the code references them by an abstract name.
I think I should add that if you're using a server, how to configure it and how to get the connections to your code will vary by server and J2EE level so post your environment. Using the Properties class is pretty obvious just by looking at the javadoc and the load() methods.
In glassfish, go to the admin console and under Resources create a new connection pool. That defines your database connection and will share a pool of those connections among your applications. Now under JDBC Resources, create a new entry that maps that pool to a name. The name is usually something like jdbc/myappname.
For a J2EE5 or later application, you can now add this as a class level variable:
#Resource(mappedName="jdbc/myappname") DataSource myDS;
At runtime the server will inject that resource to your database pool. Then when you need a connection, you can do this inside any method:
Connection conn = myDS.getConnection();
The result is your code doesn't have to care at all about the database connection information or managing a pool of connections. You can deploy the identical code on development and production servers, and they will get an appropriate connection. In order to get the injection, it has to be a class the server creates like an EJB, servlet, tag library handler, or JSF managed bean.
I've tried researching how to use the DataSource method of connecting to a database but never could find out how. I know that a DataSource is first configured and registered to JNDI in an application that is separate from the user application, and all the user application will do is retrieve it using JNDI. What I don't understand is where the DataSource is configured. Is it automatically registered when I turn on MySQL, do I need to download another application to register it, or do I make a new class that will do that for me?
You usually have a Java EE app server like Glassfish, WebLogic, JBOSS, Tomcat, or Jetty have a JNDI provider that you should be using for the lookup.
Here's how you do it with Oracle.
Here's how you do it with MySQL.
The JDK 6 javadocs say that a basic DataSource can supply a connection if your driver has such an implementation. I would recommend looking at the Connector-J docs to see if you can do it without JNDI lookup services.
First question from me on stack overflow.
I have created a java web application containing a web service using netbeans (I hope a web application were the correct choice). I use the web application as is with no extra frameworks. This web service use a sqlite JDBC driver for accessing a sqlite database file.
My problem is that the file path end up incorrect when I try to form the JDBC connection string. Also, the working directory is different when deploying and when running JUnit tests. I read somewhere about including the file as a resource, but examples of this were nowhere to be seen.
In any case, what is the best way to open the sqlite database, both when the web service is deployed and when I test it "locally"?
I don't know much about web services, I just need it to work, so please, help me with the technicalities.
Update
To put this a litle bit in context, some "println" code gives this:
Printing the work directory from a simple JUnit test gives
C:\MinaFiler\Work\SOA\BusTimetableWS
Invoking a similar web servic method returns
C:\Program Files\sges-v3\glassfish\domains\domain1
The connection string is formed from prepending "jdbc:sqlite:" to the path which at the moment is absolute:
C:\MinaFiler\Work\SOA\BusTimetableWS\src\java\miun\bustimetable\database\sqlit\BusTimetableWS.db
However, this fails because my tests throws exceptions stating database tables doesn't exist although they really do, I can see them with sqlite3.exe .
One way would be to use a config file that you can read and fetch your connection string from there.
I'm sure the framework you are using has some kind of standard way of saving configurations.
Another option would be to place the db in a known relative path from your main execution files. Then when executed fetch your current directory, and look for the db from that path.
In any case, what is the best way to open the sqlite database, both when the web service is deployed and when I test it "locally"?
The web service should use a DataSource to retrieve a connection from a connection pool configured at the application server level. In your unit test, use whatever you want (a standalone connection pool, a direct JDBC connection).
But in both cases, why don't you use an absolute path to the database file in your jdbc url? From How to Specify Database Files:
jdbc:sqlite:C:/work/mydatabase.db
The working directory wouldn't matter if you do so.