summaryrefslogtreecommitdiff
path: root/.html/java/stop-using-class-dot-forname.html
blob: 85190e868b0f7a427936769d0779e4adffb5bebc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<!DOCTYPE html>
<html>
<head>
	<title>
		The Codex » 
		Stop Using Class Dot Forname
	</title>

	<link
		rel='stylesheet'
		type='text/css'
		href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
	<link
		rel="stylesheet"
		type="text/css"
		href="../media/css/reset.css">
	<link
		rel="stylesheet"
		type="text/css"
		href="../media/css/grimoire.css">
</head>
<body>

<div id="shell">
	
		<ol id="breadcrumbs">
			
				<li class="crumb-0 not-last">
					
						<a href="../">index</a>
					
				</li>
			
				<li class="crumb-1 not-last">
					
						<a href="./">java</a>
					
				</li>
			
				<li class="crumb-2 last">
					
						stop-using-class-dot-forname
					
				</li>
			
		</ol>
	

	
	<div id="article">
		<h1 id="jdbc-drivers-and-classforname">JDBC Drivers and <code>Class.forName()</code></h1>
<p>The short version: stop using <code>Class.forName(driverClass)</code> to load JDBC
drivers. You don't need this, and haven't since Java 6. You arguably never
needed this.</p>
<p>This pattern appears all over the internet, and it's wrong.</p>
<h2 id="backstory">Backstory</h2>
<p>JDBC has more or less always provided two ways to set up <code>Connection</code> objects:</p>
<ol>
<li>
<p>Obtain them from a driver-provided <code>DataSource</code> class, which applications or
   containers are expected to create for themselves.</p>
</li>
<li>
<p>Obtain them by passing a URL to <code>DriverManager</code>.</p>
</li>
</ol>
<p>Most people start with the latter, since it's very straightforward to use.
However, <code>DriverManager</code> needs to be able to locate <code>Driver</code> subclasses, and
the JVM doesn't permit class enumeration at runtime.</p>
<p>In the original JDBC release, <code>Driver</code> subclasses were expected to register
themselves on load, similar to</p>
<pre><code>public class ExampleDriver extends Driver {
    static {
        DriverManager.registerDriver(ExampleDriver.class);
    }
}
</code></pre>
<p>Obviously, applications <em>can</em> force drivers to load using
<code>Class.forName(driverName)</code>, but this hasn't ever been the only way to do it.
<code>DriverManager</code> also provides <a href="https://docs.oracle.com/javase/8/docs/api/java/sql/DriverManager.html">a mechanism to load a set of named classes at
startup</a>,
via the <code>jdbc.drivers</code> <a href="http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html">system property</a>.</p>
<h2 id="jdbc-4-fixed-that">JDBC 4 Fixed That</h2>
<p>JDBC 4, which came out with Java 6 in the Year of our Lord <em>Two Thousand and
Six</em>, also loads drivers using the <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Service%20Provider">service
provider</a>
system, which requires no intervention at all from deployers or application
developers.</p>
<p><em>You don't need to write any code to load a JDBC 4 driver.</em></p>
<h2 id="whats-the-harm">What's The Harm?</h2>
<p>It's harmless in the immediate sense: forcing a driver to load immediately
before JDBC would load it itself has no additional side effects. However, it's
a pretty clear indicator that you've copied someone else's code without
thoroughly understanding what it does, which is a bad habit.</p>
<h2 id="but-what-about-my-database">But What About My Database?</h2>
<p>You don't need to worry about it. All of the following drivers support JDBC
4-style automatic discovery:</p>
<ul>
<li>
<p>PostgreSQL (since version 8.0-321, in 2007)</p>
</li>
<li>
<p>Firebird (since <a href="http://tracker.firebirdsql.org/browse/JDBC-140">version 2.2, in 2009</a>)</p>
</li>
<li>
<p><a href="../mysql/choose-something-else">MySQL</a> (since <a href="http://dev.mysql.com/doc/relnotes/connector-j/en/news-5-0-0.html">version 5.0, in 2005</a>)</p>
</li>
<li>
<p>H2 (since day 1, as far as I can tell)</p>
</li>
<li>
<p>Derby/JavaDB (since <a href="https://issues.apache.org/jira/browse/DERBY-930">version 10.2.1.6, in 2006</a>)</p>
</li>
<li>
<p>SQL Server (version unknown, because MSDN is archaeologically hostile)</p>
</li>
</ul>
	</div>


	
<div id="comments">
<div id="disqus_thread"></div>
<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</div>


	
	<div id="footer">
		<p>
			
				The Codex —
			
			Powered by <a href="http://markdoc.org/">Markdoc</a>.
			
<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/java/stop-using-class-dot-forname.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/java/stop-using-class-dot-forname.md">history</a>).

		</p>
	</div>
	
</div>
</body>
</html>