提问人:Sreejesh 提问时间:10/31/2023 最后编辑:Sreejesh 更新时间:11/3/2023 访问量:160
原因:java.lang.NoSuchFieldException:修饰符
Caused by: java.lang.NoSuchFieldException: modifiers
问:
我正在处理现有的旧spring-boot代码,同时迁移/升级到spring-boot 2.7.16和jdk版本从8升级到21我收到此错误
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.simple.AbstractJdbcCall;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
public class CustomJDBCCall extends SimpleJdbcCall {
private final CustomCallMetaDataContext callMetaDataContext;
private static final String CALL_META_DATA_CONTEXT = "callMetaDataContext";
private static final String MODIFIERS = "modifiers";
private static final Logger LOGGER =Logger.getLogger(CustomJDBCCall.class);
public CustomJDBCCall(JdbcTemplate jdbcTemplate) throws Exception {
super(jdbcTemplate);
try {
callMetaDataContext = new CustomCallMetaDataContext();
// Access private field
Field callMetaDataContextField =
AbstractJdbcCall.class.getDeclaredField(CALL_META_DATA_CONTEXT);
callMetaDataContextField.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField(MODIFIERS);
modifiersField.setAccessible(true);
modifiersField.setInt(callMetaDataContextField,
callMetaDataContextField.getModifiers() & ~Modifier.FINAL);
callMetaDataContextField.set(this, this.callMetaDataContext);
} catch (NoSuchFieldException | IllegalAccessException ex) {
LOGGER.error("Error while using custom JDBC", ex);
throw new RuntimeException("Exception thrown overriding
AbstractJdbcCall.callMetaDataContext field", ex);
} catch (Exception ex) {
LOGGER.error("Error while using custom JDBC", ex);
throw ex;
}
}
public List<SqlParameter> getParamerters() throws Exception {
return this.callMetaDataContext.getCallParameters();
}
}
在此代码中,在行中引发异常
Field modifiersField = Field.class.getDeclaredField(MODIFIERS);
原因:java.lang.NoSuchFieldException:修饰符 在 java.base/java.lang.Class.getDeclaredField(Class.java:2782)
之前它在 jdk 8 中工作正常。 这是不是我编写的现有代码,我认为在这里访问私有最终字段并设置值。我说得对吗? 我认为在 Jdk 版本 12 及更高版本中,无法或禁用修改最终和私有变量,是否有任何解决方法?
答:
0赞
Sreejesh
11/3/2023
#1
在项目文件夹中添加了具有确切包名称的弹簧类 AbstractJdbcCall.java。 然后添加以下方法返回 callMetaDataContext
public CallMetaDataContext getCallMetaDataContext() {
return this.callMetaDataContext;
}
现在 CustomJDBCCall 看起来像这样
public class CustomJDBCCall extends SimpleJdbcCall {
public CustomJDBCCall(JdbcTemplate jdbcTemplate) throws Exception
{
super(jdbcTemplate);
}
public List<SqlParameter> getParamerters() throws Exception {
return this.getCallMetaDataContext().getCallParameters();
}
}
这解决了我的问题
评论
java.lang.reflect.Field
static
callMetaDataContextField.setAccessible(true);
Field callMetaDataContextField = AbstractJdbcCall.class.getDeclaredField(CALL_META_DATA_CONTEXT); callMetaDataContextField.setAccessible(true); callMetaDataContextField.set(this, this.callMetaDataContext);
setAccessible(true)
既可以忽略修饰符,也可以用于非静态字段的修饰符。您的后续错误是一个完全不同的问题。一般来说,也许您的框架(现在)的工作方式不兼容。private
final
CustomCallMetaDataContext