Reputation: 27899
Looking at the following code snippet, the scenario given is about fetching a database connection from a database connection pool in the Tomcat Server.
public final class DatabaseConnection {
private static DataSource dataSource;
static {
try {
Context initContext = new InitialContext();
Context context = (Context) initContext.lookup("java:comp/env");
dataSource = (DataSource) context.lookup("jdbc/assignment_db");
} catch (NamingException e) {
Logger.getLogger(DatabaseConnection.class.getName()).log(Level.SEVERE, null, e);
}
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
I would like making the only field in the class final
. If I make it a final
field then, the compiler complains,
variable dataSource might not have been initialized.
After making it final
, if it is initialized to null
at the declaration place then, further initialization of this field in the try
block is severely forbidden causing a compilation error,
cannot assign a value to final variable dataSource.
NamingException
is a checked exception. Hence, it must be caught or declared to be thrown.
Earlier, there was a different scenario. The strategy was to use Apache DBCP as follows.
public final class DatabaseConnection {
private static final BasicDataSource basicDataSource;
static {
basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3306/assignment_db");
basicDataSource.setUsername("Tiny");
basicDataSource.setPassword("root");
}
public static Connection getConnection() throws SQLException {
return basicDataSource.getConnection();
}
}
In which, the field could be declared final
because there is no checked exception and try...catch
is unnecessary.
Can I somehow make dataSource
final as in the first case?
Upvotes: 0
Views: 1455
Reputation: 213371
This has got me stuck many times, until I found out a workaround. You can use a temporary variable in the static
block, and assign the dataSource
after try-catch
ends using that variable:
private static final DataSource dataSource;
static
{
DataSource tempDataSource = null;
try
{
Context initContext = new InitialContext();
Context context = (Context) initContext.lookup("java:comp/env");
tempDataSource = (DataSource) context.lookup("jdbc/assignment_db");
} catch (NamingException ex) {
Logger.getLogger(DatabaseConnection.class.getName()).log(Level.SEVERE, null, ex);
}
dataSource = tempDataSource;
}
However, I would rather not follow normally, and throw the exception from the catch
block only if dataSource
is not initialized, in which case, you won't need a local variable:
static
{
try
{
Context initContext = new InitialContext();
Context context = (Context) initContext.lookup("java:comp/env");
dataSource = (DataSource) context.lookup("jdbc/assignment_db");
} catch (NamingException ex) {
Logger.getLogger(DatabaseConnection.class.getName()).log(Level.SEVERE, null, ex);
throw new ExceptionInInitializerError("dataSource not initialized");
}
}
Upvotes: 2