Skip to content

Commit 9e337d2

Browse files
committed
Avoid a hard dependency on Sun's CachedRowSetImpl class
Also using the JDBC 4.1 RowSetProvider API directly instead of going through reflection, since we're building on JDK 7 now.
1 parent e2f418a commit 9e337d2

File tree

1 file changed

+55
-21
lines changed

1 file changed

+55
-21
lines changed

spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlRowSetResultSetExtractor.java

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,20 +16,21 @@
1616

1717
package org.springframework.jdbc.core;
1818

19-
import java.lang.reflect.Method;
2019
import java.sql.ResultSet;
2120
import java.sql.SQLException;
2221
import javax.sql.rowset.CachedRowSet;
22+
import javax.sql.rowset.RowSetFactory;
23+
import javax.sql.rowset.RowSetProvider;
2324

2425
import com.sun.rowset.CachedRowSetImpl;
2526

27+
import org.springframework.core.JdkVersion;
2628
import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet;
2729
import org.springframework.jdbc.support.rowset.SqlRowSet;
28-
import org.springframework.util.ReflectionUtils;
2930

3031
/**
31-
* ResultSetExtractor implementation that returns a Spring SqlRowSet
32-
* representation for each given ResultSet.
32+
* {@link ResultSetExtractor} implementation that returns a Spring {@link SqlRowSet}
33+
* representation for each given {@link ResultSet}.
3334
*
3435
* <p>The default implementation uses a standard JDBC CachedRowSet underneath.
3536
* This means that JDBC RowSet support needs to be available at runtime:
@@ -45,20 +46,16 @@
4546
*/
4647
public class SqlRowSetResultSetExtractor implements ResultSetExtractor<SqlRowSet> {
4748

48-
private static Object rowSetFactory = null;
49-
50-
private static Method createCachedRowSet = null;
49+
private static final CachedRowSetFactory cachedRowSetFactory;
5150

5251
static {
53-
ClassLoader cl = SqlRowSetResultSetExtractor.class.getClassLoader();
54-
try {
55-
Class rowSetProviderClass = cl.loadClass("javax.sql.rowset.RowSetProvider");
56-
Method newFactory = rowSetProviderClass.getMethod("newFactory");
57-
rowSetFactory = ReflectionUtils.invokeMethod(newFactory, null);
58-
createCachedRowSet = rowSetFactory.getClass().getMethod("createCachedRowSet");
52+
if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_17) {
53+
// using JDBC 4.1 RowSetProvider
54+
cachedRowSetFactory = new StandardCachedRowSetFactory();
5955
}
60-
catch (Exception ex) {
56+
else {
6157
// JDBC 4.1 API not available - fall back to Sun CachedRowSetImpl
58+
cachedRowSetFactory = new SunCachedRowSetFactory();
6259
}
6360
}
6461

@@ -88,19 +85,56 @@ protected SqlRowSet createSqlRowSet(ResultSet rs) throws SQLException {
8885
/**
8986
* Create a new CachedRowSet instance, to be populated by
9087
* the <code>createSqlRowSet</code> implementation.
91-
* <p>The default implementation creates a new instance of
92-
* Sun's <code>com.sun.rowset.CachedRowSetImpl</code> class.
88+
* <p>The default implementation uses JDBC 4.1's RowSetProvider
89+
* when running on JDK 7 or higher, falling back to Sun's
90+
* <code>com.sun.rowset.CachedRowSetImpl</code> class on older JDKs.
9391
* @return a new CachedRowSet instance
9492
* @throws SQLException if thrown by JDBC methods
9593
* @see #createSqlRowSet
9694
* @see com.sun.rowset.CachedRowSetImpl
9795
*/
9896
protected CachedRowSet newCachedRowSet() throws SQLException {
99-
if (createCachedRowSet != null) {
100-
// RowSetProvider.newFactory().createCachedRowSet();
101-
return (CachedRowSet) ReflectionUtils.invokeJdbcMethod(createCachedRowSet, rowSetFactory);
97+
return cachedRowSetFactory.createCachedRowSet();
98+
}
99+
100+
101+
/**
102+
* Internal strategy interface for the creation of CachedRowSet instances.
103+
*/
104+
private interface CachedRowSetFactory {
105+
106+
CachedRowSet createCachedRowSet() throws SQLException;
107+
}
108+
109+
110+
/**
111+
* Inner class to avoid a hard dependency on JDBC 4.1 RowSetProvider class.
112+
*/
113+
private static class StandardCachedRowSetFactory implements CachedRowSetFactory {
114+
115+
private final RowSetFactory rowSetFactory;
116+
117+
public StandardCachedRowSetFactory() {
118+
try {
119+
this.rowSetFactory = RowSetProvider.newFactory();
120+
}
121+
catch (SQLException ex) {
122+
throw new IllegalStateException("Cannot create RowSetFactory through RowSetProvider", ex);
123+
}
102124
}
103-
else {
125+
126+
public CachedRowSet createCachedRowSet() throws SQLException {
127+
return this.rowSetFactory.createCachedRowSet();
128+
}
129+
}
130+
131+
132+
/**
133+
* Inner class to avoid a hard dependency on Sun's CachedRowSetImpl class.
134+
*/
135+
private static class SunCachedRowSetFactory implements CachedRowSetFactory {
136+
137+
public CachedRowSet createCachedRowSet() throws SQLException {
104138
return new CachedRowSetImpl();
105139
}
106140
}

0 commit comments

Comments
 (0)