Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (101)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (309)
Collections:
Other Resources:
Source Code for Connector/J 8.0.31 - User Impl
Where to get the Java source code for Connector/J 8.0 User Impl module?
✍: FYIcenter.com
Java source code files for Connector/J 8.0 User Impl module are:
⏎ com/mysql/cj/jdbc/CallableStatement.java
/* * Copyright (c) 2002, 2022, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, version 2.0, as published by the * Free Software Foundation. * * This program is also distributed with certain software (including but not * limited to OpenSSL) that is licensed under separate terms, as designated in a * particular file or component or in included license documentation. The * authors of MySQL hereby grant you an additional permission to link the * program and your derivative works with the separately licensed software that * they have included with MySQL. * * Without limiting anything contained in the foregoing, this file, which is * part of MySQL Connector/J, is also subject to the Universal FOSS Exception, * version 1.0, a copy of which can be found at * http://oss.oracle.com/licenses/universal-foss-exception. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, * for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.mysql.cj.jdbc; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.JDBCType; import java.sql.NClob; import java.sql.ParameterMetaData; import java.sql.Ref; import java.sql.ResultSet; import java.sql.RowId; import java.sql.SQLException; import java.sql.SQLType; import java.sql.SQLXML; import java.sql.Time; import java.sql.Timestamp; import java.sql.Wrapper; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.mysql.cj.Messages; import com.mysql.cj.MysqlType; import com.mysql.cj.QueryInfo; import com.mysql.cj.PreparedQuery; import com.mysql.cj.conf.PropertyDefinitions.DatabaseTerm; import com.mysql.cj.conf.PropertyKey; import com.mysql.cj.exceptions.FeatureNotAvailableException; import com.mysql.cj.exceptions.MysqlErrorNumbers; import com.mysql.cj.jdbc.exceptions.SQLError; import com.mysql.cj.jdbc.result.ResultSetImpl; import com.mysql.cj.jdbc.result.ResultSetInternalMethods; import com.mysql.cj.protocol.a.result.ByteArrayRow; import com.mysql.cj.protocol.a.result.ResultsetRowsStatic; import com.mysql.cj.result.DefaultColumnDefinition; import com.mysql.cj.result.Field; import com.mysql.cj.result.Row; import com.mysql.cj.util.SearchMode; import com.mysql.cj.util.StringUtils; import com.mysql.cj.util.Util; /** * Representation of stored procedures for JDBC */ public class CallableStatement extends ClientPreparedStatement implements java.sql.CallableStatement { protected static class CallableStatementParam { int index; int inOutModifier; boolean isIn; boolean isOut; int jdbcType; short nullability; String paramName; int precision; int scale; String typeName; MysqlType desiredMysqlType = MysqlType.UNKNOWN; CallableStatementParam(String name, int idx, boolean in, boolean out, int jdbcType, String typeName, int precision, int scale, short nullability, int inOutModifier) { this.paramName = name; this.isIn = in; this.isOut = out; this.index = idx; this.jdbcType = jdbcType; this.typeName = typeName; this.precision = precision; this.scale = scale; this.nullability = nullability; this.inOutModifier = inOutModifier; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class CallableStatementParamInfo implements ParameterMetaData { String dbInUse; boolean isFunctionCall; String nativeSql; int numParameters; List<CallableStatementParam> parameterList; Map<String, CallableStatementParam> parameterMap; /** * synchronized externally in checkReadOnlyProcedure() */ boolean isReadOnlySafeProcedure = false; /** * synchronized externally in checkReadOnlyProcedure() */ boolean isReadOnlySafeChecked = false; /** * Constructor that converts a full list of parameter metadata into one * that only represents the placeholders present in the {CALL ()}. * * @param fullParamInfo * the metadata for all parameters for this stored * procedure or function. */ CallableStatementParamInfo(CallableStatementParamInfo fullParamInfo) { this.nativeSql = ((PreparedQuery) CallableStatement.this.query).getOriginalSql(); this.dbInUse = CallableStatement.this.getCurrentDatabase(); this.isFunctionCall = fullParamInfo.isFunctionCall; @SuppressWarnings("synthetic-access") int[] localParameterMap = CallableStatement.this.placeholderToParameterIndexMap; int parameterMapLength = localParameterMap.length; this.isReadOnlySafeProcedure = fullParamInfo.isReadOnlySafeProcedure; this.isReadOnlySafeChecked = fullParamInfo.isReadOnlySafeChecked; this.parameterList = new ArrayList<>(fullParamInfo.numParameters); this.parameterMap = new HashMap<>(fullParamInfo.numParameters); if (this.isFunctionCall) { // Take the return value this.parameterList.add(fullParamInfo.parameterList.get(0)); } int offset = this.isFunctionCall ? 1 : 0; for (int i = 0; i < parameterMapLength; i++) { if (localParameterMap[i] != 0) { CallableStatementParam param = fullParamInfo.parameterList.get(localParameterMap[i] + offset); this.parameterList.add(param); this.parameterMap.put(param.paramName, param); } } this.numParameters = this.parameterList.size(); } @SuppressWarnings("synthetic-access") CallableStatementParamInfo(java.sql.ResultSet paramTypesRs) throws SQLException { boolean hadRows = paramTypesRs.last(); this.nativeSql = ((PreparedQuery) CallableStatement.this.query).getOriginalSql(); this.dbInUse = CallableStatement.this.getCurrentDatabase(); this.isFunctionCall = CallableStatement.this.callingStoredFunction; if (hadRows) { this.numParameters = paramTypesRs.getRow(); this.parameterList = new ArrayList<>(this.numParameters); this.parameterMap = new HashMap<>(this.numParameters); paramTypesRs.beforeFirst(); addParametersFromDBMD(paramTypesRs); } else { this.numParameters = 0; } if (this.isFunctionCall) { this.numParameters += 1; } } private void addParametersFromDBMD(java.sql.ResultSet paramTypesRs) throws SQLException { int i = 0; while (paramTypesRs.next()) { String paramName = paramTypesRs.getString(4); int inOutModifier; switch (paramTypesRs.getInt(5)) { case DatabaseMetaData.procedureColumnIn: inOutModifier = ParameterMetaData.parameterModeIn; break; case DatabaseMetaData.procedureColumnInOut: inOutModifier = ParameterMetaData.parameterModeInOut; break; case DatabaseMetaData.procedureColumnOut: case DatabaseMetaData.procedureColumnReturn: inOutModifier = ParameterMetaData.parameterModeOut; break; default: inOutModifier = ParameterMetaData.parameterModeUnknown; } boolean isOutParameter = false; boolean isInParameter = false; if (i == 0 && this.isFunctionCall) { isOutParameter = true; isInParameter = false; } else if (inOutModifier == java.sql.DatabaseMetaData.procedureColumnInOut) { isOutParameter = true; isInParameter = true; } else if (inOutModifier == java.sql.DatabaseMetaData.procedureColumnIn) { isOutParameter = false; isInParameter = true; } else if (inOutModifier == java.sql.DatabaseMetaData.procedureColumnOut) { isOutParameter = true; isInParameter = false; } int jdbcType = paramTypesRs.getInt(6); String typeName = paramTypesRs.getString(7); int precision = paramTypesRs.getInt(8); int scale = paramTypesRs.getInt(10); short nullability = paramTypesRs.getShort(12); CallableStatementParam paramInfoToAdd = new CallableStatementParam(paramName, i++, isInParameter, isOutParameter, jdbcType, typeName, precision, scale, nullability, inOutModifier); this.parameterList.add(paramInfoToAdd); this.parameterMap.put(paramName, paramInfoToAdd); } } protected void checkBounds(int paramIndex) throws SQLException { int localParamIndex = paramIndex - 1; if ((paramIndex < 0) || (localParamIndex >= this.numParameters)) { throw SQLError.createSQLException(Messages.getString("CallableStatement.11", new Object[] { paramIndex, this.numParameters }), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } CallableStatementParam getParameter(int index) { return this.parameterList.get(index); } CallableStatementParam getParameter(String name) { return this.parameterMap.get(name); } @Override public String getParameterClassName(int arg0) throws SQLException { String mysqlTypeName = getParameterTypeName(arg0); MysqlType mysqlType = MysqlType.getByName(mysqlTypeName); switch (mysqlType) { case YEAR: if (!CallableStatement.this.session.getPropertySet().getBooleanProperty(PropertyKey.yearIsDateType).getValue()) { return Short.class.getName(); } // TODO Adjust for pseudo-boolean ? //if (length == 1) { // if (propertySet.getBooleanReadableProperty(PropertyKey.transformedBitIsBoolean).getValue()) { // return MysqlType.BOOLEAN; // } else if (propertySet.getBooleanReadableProperty(PropertyKey.tinyInt1isBit).getValue()) { // return MysqlType.BIT; // } //} return mysqlType.getClassName(); default: return mysqlType.getClassName(); } } @Override public int getParameterCount() throws SQLException { if (this.parameterList == null) { return 0; } return this.parameterList.size(); } @Override public int getParameterMode(int arg0) throws SQLException { checkBounds(arg0); return getParameter(arg0 - 1).inOutModifier; } @Override public int getParameterType(int arg0) throws SQLException { checkBounds(arg0); return getParameter(arg0 - 1).jdbcType; } @Override public String getParameterTypeName(int arg0) throws SQLException { checkBounds(arg0); return getParameter(arg0 - 1).typeName; } @Override public int getPrecision(int arg0) throws SQLException { checkBounds(arg0); return getParameter(arg0 - 1).precision; } @Override public int getScale(int arg0) throws SQLException { checkBounds(arg0); return getParameter(arg0 - 1).scale; } @Override public int isNullable(int arg0) throws SQLException { checkBounds(arg0); return getParameter(arg0 - 1).nullability; } @Override public boolean isSigned(int arg0) throws SQLException { checkBounds(arg0); return false; } Iterator<CallableStatementParam> iterator() { return this.parameterList.iterator(); } int numberOfParameters() { return this.numParameters; } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { checkClosed(); // This works for classes that aren't actually wrapping anything return iface.isInstance(this); } @Override public <T> T unwrap(Class<T> iface) throws java.sql.SQLException { try { // This works for classes that aren't actually wrapping anything return iface.cast(this); } catch (ClassCastException cce) { throw SQLError.createSQLException(Messages.getString("Common.UnableToUnwrap", new Object[] { iface.toString() }), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } } private final static int NOT_OUTPUT_PARAMETER_INDICATOR = Integer.MIN_VALUE; private final static String PARAMETER_NAMESPACE_PREFIX = "@com_mysql_jdbc_outparam_"; private static String mangleParameterName(String origParameterName) { if (origParameterName == null) { return null; } int offset = 0; if (origParameterName.length() > 0 && origParameterName.charAt(0) == '@') { offset = 1; } StringBuilder paramNameBuf = new StringBuilder(PARAMETER_NAMESPACE_PREFIX.length() + origParameterName.length()); paramNameBuf.append(PARAMETER_NAMESPACE_PREFIX); paramNameBuf.append(origParameterName.substring(offset)); return paramNameBuf.toString(); } private boolean callingStoredFunction = false; private ResultSetInternalMethods functionReturnValueResults; private boolean hasOutputParams = false; private ResultSetInternalMethods outputParameterResults; protected boolean outputParamWasNull = false; private int[] parameterIndexToRsIndex; protected CallableStatementParamInfo paramInfo; private CallableStatementParam returnValueParam; private boolean noAccessToProcedureBodies; /** * Creates a new CallableStatement * * @param conn * the connection creating this statement * @param paramInfo * the SQL to prepare * * @throws SQLException * if an error occurs */ public CallableStatement(JdbcConnection conn, CallableStatementParamInfo paramInfo) throws SQLException { super(conn, paramInfo.nativeSql, paramInfo.dbInUse); this.paramInfo = paramInfo; this.callingStoredFunction = this.paramInfo.isFunctionCall; if (this.callingStoredFunction) { ((PreparedQuery) this.query).setParameterCount(((PreparedQuery) this.query).getParameterCount() + 1); } this.retrieveGeneratedKeys = true; // not provided for in the JDBC spec this.noAccessToProcedureBodies = conn.getPropertySet().getBooleanProperty(PropertyKey.noAccessToProcedureBodies).getValue(); } /** * Creates a callable statement instance * * @param conn * the connection creating this statement * @param sql * the SQL to prepare * @param db * the current database * @param isFunctionCall * is it a function call or a procedure call? * @return CallableStatement * @throws SQLException * if an error occurs */ protected static CallableStatement getInstance(JdbcConnection conn, String sql, String db, boolean isFunctionCall) throws SQLException { return new CallableStatement(conn, sql, db, isFunctionCall); } /** * Creates a callable statement instance * * @param conn * the connection creating this statement * @param paramInfo * the SQL to prepare * @return CallableStatement * @throws SQLException * if an error occurs */ protected static CallableStatement getInstance(JdbcConnection conn, CallableStatementParamInfo paramInfo) throws SQLException { return new CallableStatement(conn, paramInfo); } private int[] placeholderToParameterIndexMap; private void generateParameterMap() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (this.paramInfo == null) { return; } // if the user specified some parameters as literals, we need to provide a map from the specified placeholders to the actual parameter numbers int parameterCountFromMetaData = this.paramInfo.getParameterCount(); // Ignore the first ? if this is a stored function, it doesn't count if (this.callingStoredFunction) { parameterCountFromMetaData--; } PreparedQuery q = ((PreparedQuery) this.query); if (this.paramInfo != null && q.getParameterCount() != parameterCountFromMetaData) { this.placeholderToParameterIndexMap = new int[q.getParameterCount()]; int startPos = this.callingStoredFunction ? StringUtils.indexOfIgnoreCase(q.getOriginalSql(), "SELECT") : StringUtils.indexOfIgnoreCase(q.getOriginalSql(), "CALL"); if (startPos != -1) { int parenOpenPos = q.getOriginalSql().indexOf('(', startPos + 4); if (parenOpenPos != -1) { int parenClosePos = StringUtils.indexOfIgnoreCase(parenOpenPos, q.getOriginalSql(), ")", "'", "'", SearchMode.__FULL); if (parenClosePos != -1) { List<?> parsedParameters = StringUtils.split(q.getOriginalSql().substring(parenOpenPos + 1, parenClosePos), ",", "'\"", "'\"", true); int numParsedParameters = parsedParameters.size(); // sanity check if (numParsedParameters != q.getParameterCount()) { // bail? } int placeholderCount = 0; for (int i = 0; i < numParsedParameters; i++) { if (((String) parsedParameters.get(i)).equals("?")) { this.placeholderToParameterIndexMap[placeholderCount++] = i; } } } } } } } } /** * Creates a new CallableStatement * * @param conn * the connection creating this statement * @param sql * the SQL to prepare * @param db * the current database * @param isFunctionCall * is it a function call or a procedure call? * * @throws SQLException * if an error occurs */ public CallableStatement(JdbcConnection conn, String sql, String db, boolean isFunctionCall) throws SQLException { super(conn, sql, db); this.callingStoredFunction = isFunctionCall; if (!this.callingStoredFunction) { if (!StringUtils.startsWithIgnoreCaseAndWs(sql, "CALL")) { // not really a stored procedure call fakeParameterTypes(false); } else { determineParameterTypes(); } generateParameterMap(); } else { determineParameterTypes(); generateParameterMap(); ((PreparedQuery) this.query).setParameterCount(((PreparedQuery) this.query).getParameterCount() + 1); } this.retrieveGeneratedKeys = true; // not provided for in the JDBC spec this.noAccessToProcedureBodies = conn.getPropertySet().getBooleanProperty(PropertyKey.noAccessToProcedureBodies).getValue(); } @Override public void addBatch() throws SQLException { setOutParams(); super.addBatch(); } private CallableStatementParam checkIsOutputParam(int paramIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (this.callingStoredFunction) { if (paramIndex == 1) { if (this.returnValueParam == null) { this.returnValueParam = new CallableStatementParam("", 0, false, true, MysqlType.VARCHAR.getJdbcType(), "VARCHAR", 0, 0, java.sql.DatabaseMetaData.attributeNullableUnknown, java.sql.DatabaseMetaData.procedureColumnReturn); } return this.returnValueParam; } // Move to position in output result set paramIndex--; } checkParameterIndexBounds(paramIndex); int localParamIndex = paramIndex - 1; if (this.placeholderToParameterIndexMap != null) { localParamIndex = this.placeholderToParameterIndexMap[localParamIndex]; } CallableStatementParam paramDescriptor = this.paramInfo.getParameter(localParamIndex); // We don't have reliable metadata in this case, trust the caller if (this.noAccessToProcedureBodies) { paramDescriptor.isOut = true; paramDescriptor.isIn = true; paramDescriptor.inOutModifier = java.sql.DatabaseMetaData.procedureColumnInOut; } else if (!paramDescriptor.isOut) { throw SQLError.createSQLException(Messages.getString("CallableStatement.9", new Object[] { paramIndex }), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } this.hasOutputParams = true; return paramDescriptor; } } /** * @param paramIndex * parameter index * * @throws SQLException * if a database access error occurs or this method is called on a closed PreparedStatement */ private void checkParameterIndexBounds(int paramIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { this.paramInfo.checkBounds(paramIndex); } } /** * Checks whether or not this statement is supposed to be providing * streamable result sets...If output parameters are registered, the driver * can not stream the results. * * @throws SQLException * if a database access error occurs */ private void checkStreamability() throws SQLException { if (this.hasOutputParams && createStreamingResultSet()) { throw SQLError.createSQLException(Messages.getString("CallableStatement.14"), MysqlErrorNumbers.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor()); } } @Override public void clearParameters() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { super.clearParameters(); try { if (this.outputParameterResults != null) { this.outputParameterResults.close(); } } finally { this.outputParameterResults = null; } } } /** * Used to fake up some metadata when we don't have access to * SHOW CREATE PROCEDURE or mysql.proc. * * @param isReallyProcedure * is it a procedure or function * * @throws SQLException * if we can't build the metadata. */ private void fakeParameterTypes(boolean isReallyProcedure) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { String encoding = this.connection.getSession().getServerSession().getCharsetSettings().getMetadataEncoding(); int collationIndex = this.connection.getSession().getServerSession().getCharsetSettings().getMetadataCollationIndex(); Field[] fields = new Field[13]; fields[0] = new Field("", "PROCEDURE_CAT", collationIndex, encoding, MysqlType.CHAR, 0); fields[1] = new Field("", "PROCEDURE_SCHEM", collationIndex, encoding, MysqlType.CHAR, 0); fields[2] = new Field("", "PROCEDURE_NAME", collationIndex, encoding, MysqlType.CHAR, 0); fields[3] = new Field("", "COLUMN_NAME", collationIndex, encoding, MysqlType.CHAR, 0); fields[4] = new Field("", "COLUMN_TYPE", collationIndex, encoding, MysqlType.CHAR, 0); fields[5] = new Field("", "DATA_TYPE", collationIndex, encoding, MysqlType.SMALLINT, 0); fields[6] = new Field("", "TYPE_NAME", collationIndex, encoding, MysqlType.CHAR, 0); fields[7] = new Field("", "PRECISION", collationIndex, encoding, MysqlType.INT, 0); fields[8] = new Field("", "LENGTH", collationIndex, encoding, MysqlType.INT, 0); fields[9] = new Field("", "SCALE", collationIndex, encoding, MysqlType.SMALLINT, 0); fields[10] = new Field("", "RADIX", collationIndex, encoding, MysqlType.SMALLINT, 0); fields[11] = new Field("", "NULLABLE", collationIndex, encoding, MysqlType.SMALLINT, 0); fields[12] = new Field("", "REMARKS", collationIndex, encoding, MysqlType.CHAR, 0); String procName = isReallyProcedure ? extractProcedureName() : null; byte[] procNameAsBytes = null; procNameAsBytes = procName == null ? null : StringUtils.getBytes(procName, "UTF-8"); ArrayList<Row> resultRows = new ArrayList<>(); for (int i = 0; i < ((PreparedQuery) this.query).getParameterCount(); i++) { byte[][] row = new byte[13][]; row[0] = null; // PROCEDURE_CAT row[1] = null; // PROCEDURE_SCHEM row[2] = procNameAsBytes; // PROCEDURE/NAME row[3] = s2b(String.valueOf(i)); // COLUMN_NAME row[4] = s2b(String.valueOf(java.sql.DatabaseMetaData.procedureColumnIn)); row[5] = s2b(String.valueOf(MysqlType.VARCHAR.getJdbcType())); // DATA_TYPE row[6] = s2b(MysqlType.VARCHAR.getName()); // TYPE_NAME row[7] = s2b(Integer.toString(65535)); // PRECISION row[8] = s2b(Integer.toString(65535)); // LENGTH row[9] = s2b(Integer.toString(0)); // SCALE row[10] = s2b(Integer.toString(10)); // RADIX row[11] = s2b(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown)); // nullable row[12] = null; resultRows.add(new ByteArrayRow(row, getExceptionInterceptor())); } java.sql.ResultSet paramTypesRs = this.resultSetFactory.createFromResultsetRows(ResultSet.CONCUR_READ_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, new ResultsetRowsStatic(resultRows, new DefaultColumnDefinition(fields))); convertGetProcedureColumnsToInternalDescriptors(paramTypesRs); } } private void determineParameterTypes() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { java.sql.ResultSet paramTypesRs = null; try { //Bug#57022, we need to check for db.SPname notation first and pass on only SPname String procName = extractProcedureName(); String quotedId = this.session.getIdentifierQuoteString(); List<?> parseList = StringUtils.splitDBdotName(procName, "", quotedId, this.session.getServerSession().isNoBackslashEscapesSet()); String tmpDb = ""; //There *should* be 2 rows, if any. if (parseList.size() == 2) { tmpDb = (String) parseList.get(0); procName = (String) parseList.get(1); } else { //keep values as they are } java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); boolean useDb = false; if (tmpDb.length() <= 0) { useDb = true; } paramTypesRs = this.session.getPropertySet().<DatabaseTerm>getEnumProperty(PropertyKey.databaseTerm).getValue() == DatabaseTerm.SCHEMA ? dbmd.getProcedureColumns(null, useDb ? this.getCurrentDatabase() : tmpDb/* null */, procName, "%") : dbmd.getProcedureColumns(useDb ? this.getCurrentDatabase() : tmpDb/* null */, null, procName, "%"); boolean hasResults = false; try { if (paramTypesRs.next()) { paramTypesRs.previous(); hasResults = true; } } catch (Exception e) { // paramTypesRs is empty, proceed with fake params. swallow, was expected } if (hasResults) { convertGetProcedureColumnsToInternalDescriptors(paramTypesRs); } else { fakeParameterTypes(true); } } finally { SQLException sqlExRethrow = null; if (paramTypesRs != null) { try { paramTypesRs.close(); } catch (SQLException sqlEx) { sqlExRethrow = sqlEx; } paramTypesRs = null; } if (sqlExRethrow != null) { throw sqlExRethrow; } } } } private void convertGetProcedureColumnsToInternalDescriptors(java.sql.ResultSet paramTypesRs) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { this.paramInfo = new CallableStatementParamInfo(paramTypesRs); } } @Override public boolean execute() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { boolean returnVal = false; checkStreamability(); setInOutParamsOnServer(); setOutParams(); returnVal = super.execute(); if (this.callingStoredFunction) { this.functionReturnValueResults = this.results; this.functionReturnValueResults.next(); this.results = null; } // TODO There is something strange here: // From ResultSetRegressionTest.testBug14562(): // // $ CREATE TABLE testBug14562 (row_order INT, signed_field MEDIUMINT, unsigned_field MEDIUMINT UNSIGNED) // $ INSERT INTO testBug14562 VALUES (1, -8388608, 0), (2, 8388607, 16777215) // $ CREATE PROCEDURE sp_testBug14562_1 (OUT param_1 MEDIUMINT, OUT param_2 MEDIUMINT UNSIGNED) // BEGIN // SELECT signed_field, unsigned_field INTO param_1, param_2 FROM testBug14562 WHERE row_order=1; // END // $ CALL sp_testBug14562_1(@com_mysql_jdbc_outparam_param_1, @com_mysql_jdbc_outparam_param_2) // $ SELECT @com_mysql_jdbc_outparam_param_1,@com_mysql_jdbc_outparam_param_2 // // ResultSet metadata returns BIGINT for @com_mysql_jdbc_outparam_param_1 and @com_mysql_jdbc_outparam_param_2 // instead of expected MEDIUMINT. I wonder what happens to other types... retrieveOutParams(); if (!this.callingStoredFunction) { return returnVal; } // Functions can't return results return false; } } @Override public java.sql.ResultSet executeQuery() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { checkStreamability(); java.sql.ResultSet execResults = null; setInOutParamsOnServer(); setOutParams(); execResults = super.executeQuery(); retrieveOutParams(); return execResults; } } @Override public int executeUpdate() throws SQLException { return Util.truncateAndConvertToInt(executeLargeUpdate()); } private String extractProcedureName() throws SQLException { String sanitizedSql = StringUtils.stripCommentsAndHints(((PreparedQuery) this.query).getOriginalSql(), "`'\"", "`'\"", !this.session.getServerSession().isNoBackslashEscapesSet()); // TODO: Do this with less memory allocation int endCallIndex = StringUtils.indexOfIgnoreCase(sanitizedSql, "CALL "); int offset = 5; if (endCallIndex == -1) { endCallIndex = StringUtils.indexOfIgnoreCase(sanitizedSql, "SELECT "); offset = 7; } if (endCallIndex != -1) { StringBuilder nameBuf = new StringBuilder(); String trimmedStatement = sanitizedSql.substring(endCallIndex + offset).trim(); int statementLength = trimmedStatement.length(); for (int i = 0; i < statementLength; i++) { char c = trimmedStatement.charAt(i); if (Character.isWhitespace(c) || (c == '(') || (c == '?')) { break; } nameBuf.append(c); } return nameBuf.toString(); } throw SQLError.createSQLException(Messages.getString("CallableStatement.1"), MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } /** * Adds 'at' symbol to beginning of parameter names if needed. * * @param paramNameIn * the parameter name to 'fix' * * @return the parameter name with an 'a' prepended, if needed * * @throws SQLException * if the parameter name is null or empty. */ protected String fixParameterName(String paramNameIn) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (paramNameIn == null) { paramNameIn = "nullpn"; } if (this.noAccessToProcedureBodies) { throw SQLError.createSQLException(Messages.getString("CallableStatement.23"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } return mangleParameterName(paramNameIn); } } @Override public Array getArray(int i) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(i); Array retValue = rs.getArray(mapOutputParameterIndexToRsIndex(i)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Array getArray(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Array retValue = rs.getArray(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public BigDecimal getBigDecimal(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); BigDecimal retValue = rs.getBigDecimal(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override @Deprecated public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); BigDecimal retValue = rs.getBigDecimal(mapOutputParameterIndexToRsIndex(parameterIndex), scale); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public BigDecimal getBigDecimal(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= BigDecimal retValue = rs.getBigDecimal(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Blob getBlob(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Blob retValue = rs.getBlob(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Blob getBlob(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Blob retValue = rs.getBlob(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public boolean getBoolean(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); boolean retValue = rs.getBoolean(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public boolean getBoolean(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= boolean retValue = rs.getBoolean(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public byte getByte(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); byte retValue = rs.getByte(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public byte getByte(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= byte retValue = rs.getByte(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public byte[] getBytes(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); byte[] retValue = rs.getBytes(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public byte[] getBytes(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= byte[] retValue = rs.getBytes(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Clob getClob(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Clob retValue = rs.getClob(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Clob getClob(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Clob retValue = rs.getClob(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Date getDate(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Date retValue = rs.getDate(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Date getDate(int parameterIndex, Calendar cal) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Date retValue = rs.getDate(mapOutputParameterIndexToRsIndex(parameterIndex), cal); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Date getDate(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Date retValue = rs.getDate(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Date getDate(String parameterName, Calendar cal) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Date retValue = rs.getDate(fixParameterName(parameterName), cal); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public double getDouble(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); double retValue = rs.getDouble(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public double getDouble(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= double retValue = rs.getDouble(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public float getFloat(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); float retValue = rs.getFloat(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public float getFloat(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= float retValue = rs.getFloat(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public int getInt(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); int retValue = rs.getInt(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public int getInt(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= int retValue = rs.getInt(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public long getLong(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); long retValue = rs.getLong(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public long getLong(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= long retValue = rs.getLong(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } protected int getNamedParamIndex(String paramName, boolean forOut) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (this.noAccessToProcedureBodies) { throw SQLError.createSQLException("No access to parameters by name when connection has been configured not to access procedure bodies", MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } if ((paramName == null) || (paramName.length() == 0)) { throw SQLError.createSQLException(Messages.getString("CallableStatement.2"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } CallableStatementParam namedParamInfo; if (this.paramInfo == null || (namedParamInfo = this.paramInfo.getParameter(paramName)) == null) { throw SQLError.createSQLException(Messages.getString("CallableStatement.3", new Object[] { paramName }), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } if (forOut && !namedParamInfo.isOut) { throw SQLError.createSQLException(Messages.getString("CallableStatement.5", new Object[] { paramName }), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } if (this.placeholderToParameterIndexMap == null) { return namedParamInfo.index + 1; // JDBC indices are 1-based } for (int i = 0; i < this.placeholderToParameterIndexMap.length; i++) { if (this.placeholderToParameterIndexMap[i] == namedParamInfo.index) { return i + 1; } } throw SQLError.createSQLException(Messages.getString("CallableStatement.6", new Object[] { paramName }), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @Override public Object getObject(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { CallableStatementParam paramDescriptor = checkIsOutputParam(parameterIndex); ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Object retVal = rs.getObjectStoredProc(mapOutputParameterIndexToRsIndex(parameterIndex), paramDescriptor.desiredMysqlType.getJdbcType()); this.outputParamWasNull = rs.wasNull(); return retVal; } } @Override public Object getObject(int parameterIndex, Map<String, Class<?>> map) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Object retVal = rs.getObject(mapOutputParameterIndexToRsIndex(parameterIndex), map); this.outputParamWasNull = rs.wasNull(); return retVal; } } @Override public Object getObject(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Object retValue = rs.getObject(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Object getObject(String parameterName, Map<String, Class<?>> map) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Object retValue = rs.getObject(fixParameterName(parameterName), map); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public <T> T getObject(int parameterIndex, Class<T> type) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); // remove cast once 1.5, 1.6 EOL'd T retVal = ((ResultSetImpl) rs).getObject(mapOutputParameterIndexToRsIndex(parameterIndex), type); this.outputParamWasNull = rs.wasNull(); return retVal; } } @Override public <T> T getObject(String parameterName, Class<T> type) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= T retValue = ((ResultSetImpl) rs).getObject(fixParameterName(parameterName), type); this.outputParamWasNull = rs.wasNull(); return retValue; } } /** * Returns the ResultSet that holds the output parameters, or throws an * appropriate exception if none exist, or they weren't returned. * * @param paramIndex * parameter index * * @return the ResultSet that holds the output parameters * * @throws SQLException * if no output parameters were defined, or if no output * parameters were returned. */ protected ResultSetInternalMethods getOutputParameters(int paramIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { this.outputParamWasNull = false; if (paramIndex == 1 && this.callingStoredFunction && this.returnValueParam != null) { return this.functionReturnValueResults; } if (this.outputParameterResults == null) { if (this.paramInfo.numberOfParameters() == 0) { throw SQLError.createSQLException(Messages.getString("CallableStatement.7"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } throw SQLError.createSQLException(Messages.getString("CallableStatement.8"), MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } return this.outputParameterResults; } } @Override public ParameterMetaData getParameterMetaData() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (this.placeholderToParameterIndexMap == null) { return this.paramInfo; } return new CallableStatementParamInfo(this.paramInfo); } } @Override public Ref getRef(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Ref retValue = rs.getRef(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Ref getRef(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Ref retValue = rs.getRef(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public short getShort(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); short retValue = rs.getShort(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public short getShort(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= short retValue = rs.getShort(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public String getString(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); String retValue = rs.getString(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public String getString(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= String retValue = rs.getString(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Time getTime(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Time retValue = rs.getTime(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Time getTime(int parameterIndex, Calendar cal) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Time retValue = rs.getTime(mapOutputParameterIndexToRsIndex(parameterIndex), cal); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Time getTime(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Time retValue = rs.getTime(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Time getTime(String parameterName, Calendar cal) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Time retValue = rs.getTime(fixParameterName(parameterName), cal); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Timestamp getTimestamp(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Timestamp retValue = rs.getTimestamp(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Timestamp retValue = rs.getTimestamp(mapOutputParameterIndexToRsIndex(parameterIndex), cal); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Timestamp getTimestamp(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName), cal); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public URL getURL(int parameterIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); URL retValue = rs.getURL(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } } @Override public URL getURL(String parameterName) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= URL retValue = rs.getURL(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } } protected int mapOutputParameterIndexToRsIndex(int paramIndex) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (this.returnValueParam != null && paramIndex == 1) { return 1; } checkParameterIndexBounds(paramIndex); int localParamIndex = paramIndex - 1; if (this.placeholderToParameterIndexMap != null) { localParamIndex = this.placeholderToParameterIndexMap[localParamIndex]; } int rsIndex = this.parameterIndexToRsIndex[localParamIndex]; if (rsIndex == NOT_OUTPUT_PARAMETER_INDICATOR) { throw SQLError.createSQLException(Messages.getString("CallableStatement.21", new Object[] { paramIndex }), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } return rsIndex + 1; } } protected void registerOutParameter(int parameterIndex, MysqlType mysqlType) throws SQLException { CallableStatementParam paramDescriptor = checkIsOutputParam(parameterIndex); paramDescriptor.desiredMysqlType = mysqlType; } @Override public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException { try { MysqlType mt = MysqlType.getByJdbcType(sqlType); registerOutParameter(parameterIndex, mt); } catch (FeatureNotAvailableException nae) { throw SQLError.createSQLFeatureNotSupportedException(Messages.getString("Statement.UnsupportedSQLType") + JDBCType.valueOf(sqlType), MysqlErrorNumbers.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor()); } } @Override public void registerOutParameter(int parameterIndex, SQLType sqlType) throws SQLException { if (sqlType instanceof MysqlType) { registerOutParameter(parameterIndex, (MysqlType) sqlType); } else { registerOutParameter(parameterIndex, sqlType.getVendorTypeNumber()); } } protected void registerOutParameter(int parameterIndex, MysqlType mysqlType, @SuppressWarnings("unused") int scale) throws SQLException { registerOutParameter(parameterIndex, mysqlType); // TODO is that correct that we ignore scale? } @Override public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException { registerOutParameter(parameterIndex, sqlType); // TODO is that correct that we ignore scale? } @Override public void registerOutParameter(int parameterIndex, SQLType sqlType, int scale) throws SQLException { if (sqlType instanceof MysqlType) { registerOutParameter(parameterIndex, (MysqlType) sqlType, scale); } else { registerOutParameter(parameterIndex, sqlType.getVendorTypeNumber(), scale); } } protected void registerOutParameter(int parameterIndex, MysqlType mysqlType, @SuppressWarnings("unused") String typeName) throws SQLException { registerOutParameter(parameterIndex, mysqlType); // TODO is that correct that we ignore typeName? } @Override public void registerOutParameter(int parameterIndex, int sqlType, String typeName) throws SQLException { try { MysqlType mt = MysqlType.getByJdbcType(sqlType); registerOutParameter(parameterIndex, mt, typeName); } catch (FeatureNotAvailableException nae) { throw SQLError.createSQLFeatureNotSupportedException(Messages.getString("Statement.UnsupportedSQLType") + JDBCType.valueOf(sqlType), MysqlErrorNumbers.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor()); } } @Override public void registerOutParameter(int parameterIndex, SQLType sqlType, String typeName) throws SQLException { if (sqlType instanceof MysqlType) { registerOutParameter(parameterIndex, (MysqlType) sqlType, typeName); } else { registerOutParameter(parameterIndex, sqlType.getVendorTypeNumber(), typeName); } } @Override public void registerOutParameter(String parameterName, int sqlType) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { registerOutParameter(getNamedParamIndex(parameterName, true), sqlType); } } @Override public void registerOutParameter(String parameterName, SQLType sqlType) throws SQLException { if (sqlType instanceof MysqlType) { registerOutParameter(getNamedParamIndex(parameterName, true), (MysqlType) sqlType); } else { registerOutParameter(getNamedParamIndex(parameterName, true), sqlType.getVendorTypeNumber()); } } @Override public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException { registerOutParameter(getNamedParamIndex(parameterName, true), sqlType, scale); } @Override public void registerOutParameter(String parameterName, SQLType sqlType, int scale) throws SQLException { if (sqlType instanceof MysqlType) { registerOutParameter(getNamedParamIndex(parameterName, true), (MysqlType) sqlType, scale); } else { registerOutParameter(getNamedParamIndex(parameterName, true), sqlType.getVendorTypeNumber(), scale); } } @Override public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException { registerOutParameter(getNamedParamIndex(parameterName, true), sqlType, typeName); } @Override public void registerOutParameter(String parameterName, SQLType sqlType, String typeName) throws SQLException { if (sqlType instanceof MysqlType) { registerOutParameter(getNamedParamIndex(parameterName, true), (MysqlType) sqlType, typeName); } else { registerOutParameter(parameterName, sqlType.getVendorTypeNumber(), typeName); } } /** * Issues a second query to retrieve all output parameters. * * @throws SQLException * if an error occurs. */ private void retrieveOutParams() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { int numParameters = this.paramInfo.numberOfParameters(); this.parameterIndexToRsIndex = new int[numParameters]; for (int i = 0; i < numParameters; i++) { this.parameterIndexToRsIndex[i] = NOT_OUTPUT_PARAMETER_INDICATOR; } int localParamIndex = 0; if (numParameters > 0) { StringBuilder outParameterQuery = new StringBuilder("SELECT "); boolean firstParam = true; boolean hadOutputParams = false; for (Iterator<CallableStatementParam> paramIter = this.paramInfo.iterator(); paramIter.hasNext();) { CallableStatementParam retrParamInfo = paramIter.next(); if (retrParamInfo.isOut) { hadOutputParams = true; this.parameterIndexToRsIndex[retrParamInfo.index] = localParamIndex++; if (retrParamInfo.paramName == null) { retrParamInfo.paramName = "nullnp" + retrParamInfo.index; } String outParameterName = mangleParameterName(retrParamInfo.paramName); if (!firstParam) { outParameterQuery.append(","); } else { firstParam = false; } if (!outParameterName.startsWith("@")) { outParameterQuery.append('@'); } outParameterQuery.append(outParameterName); } } if (hadOutputParams) { // We can't use 'ourself' to execute this query, or any pending result sets would be overwritten java.sql.Statement outParameterStmt = null; java.sql.ResultSet outParamRs = null; try { outParameterStmt = this.connection.createStatement(); outParamRs = outParameterStmt.executeQuery(outParameterQuery.toString()); this.outputParameterResults = this.resultSetFactory.createFromResultsetRows(outParamRs.getConcurrency(), outParamRs.getType(), ((com.mysql.cj.jdbc.result.ResultSetInternalMethods) outParamRs).getRows()); // note, doesn't work for updatable result sets if (!this.outputParameterResults.next()) { this.outputParameterResults.close(); this.outputParameterResults = null; } } finally { if (outParameterStmt != null) { outParameterStmt.close(); } } } else { this.outputParameterResults = null; } } else { this.outputParameterResults = null; } } } @Override public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException { setAsciiStream(getNamedParamIndex(parameterName, false), x, length); } @Override public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException { setBigDecimal(getNamedParamIndex(parameterName, false), x); } @Override public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException { setBinaryStream(getNamedParamIndex(parameterName, false), x, length); } @Override public void setBoolean(String parameterName, boolean x) throws SQLException { setBoolean(getNamedParamIndex(parameterName, false), x); } @Override public void setByte(String parameterName, byte x) throws SQLException { setByte(getNamedParamIndex(parameterName, false), x); } @Override public void setBytes(String parameterName, byte[] x) throws SQLException { setBytes(getNamedParamIndex(parameterName, false), x); } @Override public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException { setCharacterStream(getNamedParamIndex(parameterName, false), reader, length); } @Override public void setDate(String parameterName, Date x) throws SQLException { setDate(getNamedParamIndex(parameterName, false), x); } @Override public void setDate(String parameterName, Date x, Calendar cal) throws SQLException { setDate(getNamedParamIndex(parameterName, false), x, cal); } @Override public void setDouble(String parameterName, double x) throws SQLException { setDouble(getNamedParamIndex(parameterName, false), x); } @Override public void setFloat(String parameterName, float x) throws SQLException { setFloat(getNamedParamIndex(parameterName, false), x); } private void setInOutParamsOnServer() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (this.paramInfo.numParameters > 0) { for (Iterator<CallableStatementParam> paramIter = this.paramInfo.iterator(); paramIter.hasNext();) { CallableStatementParam inParamInfo = paramIter.next(); if (inParamInfo.isOut && inParamInfo.isIn) { if (inParamInfo.paramName == null) { inParamInfo.paramName = "nullnp" + inParamInfo.index; } String inOutParameterName = mangleParameterName(inParamInfo.paramName); StringBuilder queryBuf = new StringBuilder(4 + inOutParameterName.length() + 1 + 1); queryBuf.append("SET "); queryBuf.append(inOutParameterName); queryBuf.append("=?"); ClientPreparedStatement setPstmt = null; try { setPstmt = ((Wrapper) this.connection.clientPrepareStatement(queryBuf.toString())).unwrap(ClientPreparedStatement.class); setPstmt.getQueryBindings().setFromBindValue(0, ((PreparedQuery) this.query).getQueryBindings().getBindValues()[inParamInfo.index]); setPstmt.executeUpdate(); } finally { if (setPstmt != null) { setPstmt.close(); } } } } } } } @Override public void setInt(String parameterName, int x) throws SQLException { setInt(getNamedParamIndex(parameterName, false), x); } @Override public void setLong(String parameterName, long x) throws SQLException { setLong(getNamedParamIndex(parameterName, false), x); } @Override public void setNull(String parameterName, int sqlType) throws SQLException { setNull(getNamedParamIndex(parameterName, false), sqlType); } @Override public void setNull(String parameterName, int sqlType, String typeName) throws SQLException { setNull(getNamedParamIndex(parameterName, false), sqlType, typeName); } @Override public void setObject(String parameterName, Object x) throws SQLException { setObject(getNamedParamIndex(parameterName, false), x); } @Override public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException { setObject(getNamedParamIndex(parameterName, false), x, targetSqlType); } @Override public void setObject(String parameterName, Object x, SQLType targetSqlType) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { setObject(getNamedParamIndex(parameterName, false), x, targetSqlType); } } @Override public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException { setObject(getNamedParamIndex(parameterName, false), x, targetSqlType, scale); } @Override public void setObject(String parameterName, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { setObject(getNamedParamIndex(parameterName, false), x, targetSqlType, scaleOrLength); } } private void setOutParams() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (this.paramInfo.numParameters > 0) { for (Iterator<CallableStatementParam> paramIter = this.paramInfo.iterator(); paramIter.hasNext();) { CallableStatementParam outParamInfo = paramIter.next(); if (!this.callingStoredFunction && outParamInfo.isOut) { if (outParamInfo.paramName == null) { outParamInfo.paramName = "nullnp" + outParamInfo.index; } String outParameterName = mangleParameterName(outParamInfo.paramName); int outParamIndex = 0; if (this.placeholderToParameterIndexMap == null) { outParamIndex = outParamInfo.index + 1; } else { // Find it, todo: remove this linear search boolean found = false; for (int i = 0; i < this.placeholderToParameterIndexMap.length; i++) { if (this.placeholderToParameterIndexMap[i] == outParamInfo.index) { outParamIndex = i + 1; /* JDBC is 1-based */ found = true; break; } } if (!found) { throw SQLError.createSQLException(Messages.getString("CallableStatement.21", new Object[] { outParamInfo.paramName }), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } this.setBytes(outParamIndex, StringUtils.getBytes(outParameterName, this.charEncoding), false); } } } } } @Override public void setShort(String parameterName, short x) throws SQLException { setShort(getNamedParamIndex(parameterName, false), x); } @Override public void setString(String parameterName, String x) throws SQLException { setString(getNamedParamIndex(parameterName, false), x); } @Override public void setTime(String parameterName, Time x) throws SQLException { setTime(getNamedParamIndex(parameterName, false), x); } @Override public void setTime(String parameterName, Time x, Calendar cal) throws SQLException { setTime(getNamedParamIndex(parameterName, false), x, cal); } @Override public void setTimestamp(String parameterName, Timestamp x) throws SQLException { setTimestamp(getNamedParamIndex(parameterName, false), x); } @Override public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException { setTimestamp(getNamedParamIndex(parameterName, false), x, cal); } @Override public void setURL(String parameterName, URL val) throws SQLException { setURL(getNamedParamIndex(parameterName, false), val); } @Override public boolean wasNull() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { return this.outputParamWasNull; } } @Override public int[] executeBatch() throws SQLException { return Util.truncateAndConvertToInt(executeLargeBatch()); } @Override protected int getParameterIndexOffset() { if (this.callingStoredFunction) { return -1; } return super.getParameterIndexOffset(); } @Override public void setAsciiStream(String parameterName, InputStream x) throws SQLException { setAsciiStream(getNamedParamIndex(parameterName, false), x); } @Override public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException { setAsciiStream(getNamedParamIndex(parameterName, false), x, length); } @Override public void setBinaryStream(String parameterName, InputStream x) throws SQLException { setBinaryStream(getNamedParamIndex(parameterName, false), x); } @Override public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException { setBinaryStream(getNamedParamIndex(parameterName, false), x, length); } @Override public void setBlob(String parameterName, Blob x) throws SQLException { setBlob(getNamedParamIndex(parameterName, false), x); } @Override public void setBlob(String parameterName, InputStream inputStream) throws SQLException { setBlob(getNamedParamIndex(parameterName, false), inputStream); } @Override public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException { setBlob(getNamedParamIndex(parameterName, false), inputStream, length); } @Override public void setCharacterStream(String parameterName, Reader reader) throws SQLException { setCharacterStream(getNamedParamIndex(parameterName, false), reader); } @Override public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException { setCharacterStream(getNamedParamIndex(parameterName, false), reader, length); } @Override public void setClob(String parameterName, Clob x) throws SQLException { setClob(getNamedParamIndex(parameterName, false), x); } @Override public void setClob(String parameterName, Reader reader) throws SQLException { setClob(getNamedParamIndex(parameterName, false), reader); } @Override public void setClob(String parameterName, Reader reader, long length) throws SQLException { setClob(getNamedParamIndex(parameterName, false), reader, length); } @Override public void setNCharacterStream(String parameterName, Reader value) throws SQLException { setNCharacterStream(getNamedParamIndex(parameterName, false), value); } @Override public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException { setNCharacterStream(getNamedParamIndex(parameterName, false), value, length); } /** * Check whether the stored procedure alters any data or is safe for read-only usage. * * @return true if procedure does not alter data * @throws SQLException * if a database access error occurs or this method is called on a closed PreparedStatement */ private boolean checkReadOnlyProcedure() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (this.noAccessToProcedureBodies) { return false; } if (this.paramInfo.isReadOnlySafeChecked) { return this.paramInfo.isReadOnlySafeProcedure; } ResultSet rs = null; java.sql.PreparedStatement ps = null; try { String procName = extractProcedureName(); String db = this.getCurrentDatabase(); if (procName.indexOf(".") != -1) { db = procName.substring(0, procName.indexOf(".")); if (StringUtils.startsWithIgnoreCaseAndWs(db, "`") && db.trim().endsWith("`")) { db = db.substring(1, db.length() - 1); } procName = procName.substring(procName.indexOf(".") + 1); procName = StringUtils.toString(StringUtils.stripEnclosure(StringUtils.getBytes(procName), "`", "`")); } ps = this.connection.prepareStatement("SELECT SQL_DATA_ACCESS FROM information_schema.routines WHERE routine_schema = ? AND routine_name = ?"); ps.setMaxRows(0); ps.setFetchSize(0); ps.setString(1, db); ps.setString(2, procName); rs = ps.executeQuery(); if (rs.next()) { String sqlDataAccess = rs.getString(1); if ("READS SQL DATA".equalsIgnoreCase(sqlDataAccess) || "NO SQL".equalsIgnoreCase(sqlDataAccess)) { synchronized (this.paramInfo) { this.paramInfo.isReadOnlySafeChecked = true; this.paramInfo.isReadOnlySafeProcedure = true; } return true; } } } catch (SQLException e) { // swallow the Exception } finally { if (rs != null) { rs.close(); } if (ps != null) { ps.close(); } } this.paramInfo.isReadOnlySafeChecked = false; this.paramInfo.isReadOnlySafeProcedure = false; } return false; } @Override protected boolean checkReadOnlySafeStatement() throws SQLException { if (QueryInfo.isReadOnlySafeQuery(((PreparedQuery) this.query).getOriginalSql(), this.session.getServerSession().isNoBackslashEscapesSet())) { String sql = ((PreparedQuery) this.query).getOriginalSql(); int statementKeywordPos = QueryInfo.indexOfStatementKeyword(sql, this.session.getServerSession().isNoBackslashEscapesSet()); if (StringUtils.startsWithIgnoreCaseAndWs(sql, "CALL", statementKeywordPos) || StringUtils.startsWithIgnoreCaseAndWs(sql, "SELECT", statementKeywordPos)) { // "CALL" and "SELECT" are read-only safe but the routine they call may not be. if (!this.connection.isReadOnly()) { // Only proceed with checking the routine body if really needed. return true; } return checkReadOnlyProcedure(); } return true; } return !this.connection.isReadOnly(); } @Override public RowId getRowId(int parameterIndex) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); RowId retValue = rs.getRowId(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public RowId getRowId(String parameterName) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= RowId retValue = rs.getRowId(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public void setRowId(String parameterName, RowId x) throws SQLException { setRowId(getNamedParamIndex(parameterName, false), x); } @Override public void setNString(String parameterName, String value) throws SQLException { setNString(getNamedParamIndex(parameterName, false), value); } @Override public void setNClob(String parameterName, NClob value) throws SQLException { setNClob(getNamedParamIndex(parameterName, false), value); } @Override public void setNClob(String parameterName, Reader reader) throws SQLException { setNClob(getNamedParamIndex(parameterName, false), reader); } @Override public void setNClob(String parameterName, Reader reader, long length) throws SQLException { setNClob(getNamedParamIndex(parameterName, false), reader, length); } @Override public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { setSQLXML(getNamedParamIndex(parameterName, false), xmlObject); } @Override public SQLXML getSQLXML(int parameterIndex) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); SQLXML retValue = rs.getSQLXML(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public SQLXML getSQLXML(String parameterName) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= SQLXML retValue = rs.getSQLXML(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public String getNString(int parameterIndex) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); String retValue = rs.getNString(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public String getNString(String parameterName) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= String retValue = rs.getNString(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public Reader getNCharacterStream(int parameterIndex) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Reader retValue = rs.getNCharacterStream(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public Reader getNCharacterStream(String parameterName) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Reader retValue = rs.getNCharacterStream(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public Reader getCharacterStream(int parameterIndex) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); Reader retValue = rs.getCharacterStream(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public Reader getCharacterStream(String parameterName) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= Reader retValue = rs.getCharacterStream(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public NClob getNClob(int parameterIndex) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(parameterIndex); NClob retValue = rs.getNClob(mapOutputParameterIndexToRsIndex(parameterIndex)); this.outputParamWasNull = rs.wasNull(); return retValue; } @Override public NClob getNClob(String parameterName) throws SQLException { ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?= NClob retValue = rs.getNClob(fixParameterName(parameterName)); this.outputParamWasNull = rs.wasNull(); return retValue; } /** * Converts the given string to bytes, using the connection's character * encoding. * * @param s * string * @return bytes */ protected byte[] s2b(String s) { return s == null ? null : StringUtils.getBytes(s, this.charEncoding); } @Override public long executeLargeUpdate() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { long returnVal = -1; checkStreamability(); if (this.callingStoredFunction) { execute(); return -1; } setInOutParamsOnServer(); setOutParams(); returnVal = super.executeLargeUpdate(); retrieveOutParams(); return returnVal; } } @Override public long[] executeLargeBatch() throws SQLException { if (this.hasOutputParams) { throw SQLError.createSQLException("Can't call executeBatch() on CallableStatement with OUTPUT parameters", MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } return super.executeLargeBatch(); } }
⏎ com/mysql/cj/jdbc/CallableStatement.java
Or download all of them as a single archive file:
File name: mysql-connector-java-user-impl-8.0.31.zip File size: 429580 bytes Release date: 2022-09-03 Download
⇒ Downloading mysql-connector-java-5.1.40.zip
⇐ Source Code for Connector/J 8.0.31 - User API
2023-05-09, 7669👍, 0💬
Popular Posts:
JDK 11 java.management.jmod is the JMOD file for JDK 11 Management module. JDK 11 Management module ...
commons-io-1.4.jar is the JAR file for Commons IO 1.4, which is a library of utilities to assist wit...
The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms, it was develo...
Where to find answers to frequently asked questions on Downloading and Using JDK (Java Development K...
What Is fop.jar? I got it from the fop-2.7-bin.zip. fop.jar in fop-2.7-bin.zip is the JAR file for F...