-
Notifications
You must be signed in to change notification settings - Fork 578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exception analyzing ... using detector edu.umd.cs.findbugs.detect.RedundantConditions #608
Comments
Can you post the code of those classes? |
Sorry, but I cannot post the code as it's proprietary |
@gargooza : but you can try to isolate a snippet which shows the problem or you can close this issue as "can't reproduce". |
I was able to isolate the issue. I cannot actually paste code, but the problem line in each of the exceptions is an assert. If I comment out the assert, SpotBugs succeeds. The assert is nested within some loop/conditional blocks like this:
|
Happens also for me:
|
Here is the class it is complaining about - strangely enough, the build continues despite the exception public abstract class CommonMetadataConfig
extends AbstractCachingEnvironmentAwareConfigBean
implements MetadataConfigDescriptor {
public static final String DEFAULT_CONFIGURABLE_BEANS_LIST = ConfigUtils.ALL_VALUE;
private final ObjectName resourceName;
private final String selfName;
protected CommonMetadataConfig() throws JMException {
this.resourceName = Objects.requireNonNull(
MBeanExportUtils.getManagedResourceObjectName(this),
"Missing exported MBean JMX object name");
this.selfName = Validate.notBlank(
MBEAN_NAME_VALUE_EXTRACTOR.apply(resourceName),
"Missing container resource name in %s",
JmxUtils.CANONICAL_NAME_EXTRACTOR.apply(resourceName));
}
protected CommonMetadataConfig(ObjectName objectName) {
this.resourceName = Objects.requireNonNull(objectName, "Missing exported MBean JMX object name");
this.selfName = Validate.notBlank(
MBEAN_NAME_VALUE_EXTRACTOR.apply(resourceName),
"Missing container resource name in %s",
JmxUtils.CANONICAL_NAME_EXTRACTOR.apply(resourceName));
}
@Override // TODO make this a default method in Java-8
public String getPrimaryMBeanDomain() {
return JmxUtils.DOMAIN_EXTRACTOR.apply(getResourceObjectName());
}
@Override
public ObjectName getResourceObjectName() {
return resourceName;
}
public String getConfigurableMBeansNamesList() {
return StringUtils.join(getConfigurableMBeansNames(), ',');
}
@Override
public void onContextInitialized(ApplicationContext context) {
super.onContextInitialized(context);
Collection<String> namesList = getConfigurableMBeansNames();
validateMBeansNamesList(namesList, context);
}
public abstract void setConfigurableMBeansNamesList(String propValue);
// NOTE: don't really need the application context to be provided, but useful for unit tests
public void updateConfigurableMBeansNamesList(String propName, String propValue, ApplicationContext context) {
if (StringUtils.isBlank(propValue) || DEFAULT_CONFIGURABLE_BEANS_LIST.equalsIgnoreCase(propValue)) {
updateProperty(propName, DEFAULT_CONFIGURABLE_BEANS_LIST, DEFAULT_CONFIGURABLE_BEANS_LIST);
return;
}
updateConfigurableMBeansNamesList(propName, Arrays.asList(StringUtils.split(propValue, ',')), context);
}
// NOTE: don't really need the application context to be provided, but useful for unit tests
public void updateConfigurableMBeansNamesList(String propName, Collection<String> namesList, ApplicationContext context) {
validateMBeansNamesList(namesList, context);
updateProperty(propName, StringUtils.join(namesList, ','), DEFAULT_CONFIGURABLE_BEANS_LIST);
}
protected <C extends Collection<String>> C validateMBeansNamesList(C namesList, ApplicationContext context) {
Validate.validState(CollectionUtils.isNotEmpty(namesList) && namesList.contains(selfName),
"Configured names list does not contain '%s': %s", selfName, namesList);
// Make sure no repetitions (case insensitive)
Collection<String> effectiveList = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
effectiveList.addAll(namesList);
Validate.validState(effectiveList.size() == namesList.size(), "Repeated values in list: %s", namesList);
Collection<String> availableNames = detectAllConfigurableMBeansNames(context);
Validate.validState(availableNames.containsAll(namesList), "Unknown names specified in list: %s", namesList);
return namesList;
}
// NOTE: don't really need the application context to be provided, but useful for unit tests
public List<String> resolveConfigurableMBeansNames(String propName, ApplicationContext context) {
String propValue = getProperty(propName, String.class, DEFAULT_CONFIGURABLE_BEANS_LIST);
// Check if specific names listed
if (StringUtils.isNotBlank(propValue) && (!DEFAULT_CONFIGURABLE_BEANS_LIST.equalsIgnoreCase(propValue))) {
String[] namesList = StringUtils.split(propValue, ',');
return Collections.unmodifiableList(Arrays.asList(namesList));
}
return detectAllConfigurableMBeansNames(context);
}
// NOTE: don't really need the application context to be provided, but useful for unit tests
// TODO consider caching the result if repeated frequent calls
public List<String> detectAllConfigurableMBeansNames(ApplicationContext context) {
Collection<ObjectName> configNames = detectAllConfigurableMBeans(context);
if (CollectionUtils.isEmpty(configNames)) {
return Collections.emptyList();
}
return CollectionUtils.collect(configNames, MBEAN_NAME_VALUE_EXTRACTOR::apply, new ArrayList<String>(configNames.size()));
}
// NOTE: don't really need the application context to be provided, but useful for unit tests
// TODO consider caching the result if repeated frequent calls
public List<ObjectName> detectAllConfigurableMBeans(ApplicationContext context) {
// Context might be null for unit tests
Map<String, ?> beansMap = ApplicationContextUtils.getAllBeansWithAnnotation(context, PropertySource.class);
if (MapUtils.isEmpty(beansMap)) {
beansMap = ApplicationContextUtils.getAllBeansWithAnnotation(context, PropertySources.class);
}
if (MapUtils.isEmpty(beansMap)) {
return Collections.emptyList();
}
List<ObjectName> namesList = new ArrayList<>(beansMap.size());
boolean debugEnabled = logger.isDebugEnabled();
for (Map.Entry<String, ?> beanEntry : beansMap.entrySet()) {
String beanName = beanEntry.getKey();
Object beanInstance = beanEntry.getValue();
Class<?> beanClass = beanInstance.getClass();
try {
ObjectName jmxName = MBeanExportUtils.getManagedResourceObjectName(beanClass);
if (jmxName == null) {
if (debugEnabled) {
logger.debug("detectAllConfigurableMBeans({})[{}] not a managed resource", beanName, SafeUtils.safeShortName(beanClass));
}
continue;
}
String configName = MBEAN_NAME_VALUE_EXTRACTOR.apply(jmxName);
Validate.notBlank(configName, "No '" + NamedEntity.PROP_NAME + "' property in resource name='%s'", jmxName.getCanonicalName());
if (debugEnabled) {
logger.debug("detectAllConfigurableMBeans({})[{}] {}: {}",
beanName, SafeUtils.safeShortName(beanClass), jmxName.getCanonicalName(), configName);
}
namesList.add(jmxName);
} catch (Exception e) {
logger.warn("detectAllConfigurableMBeans({})[{}] failed ({}) to extract resource object name: {}",
beanName, SafeUtils.safeShortName(beanClass), e.getClass().getSimpleName(), e.getMessage());
}
}
return namesList;
}
} |
Are you able to provide the (bytecode) output of |
I can reproduce this issue. Here is my project: https://github.com/DTeam-Top/grails-rest-seed git clone --depth 1 https://github.com/DTeam-Top/grails-rest-seed.git
./gradlew spotbugsMain Will see this error:
|
The following exception is happening with Maven plugin version 4.7.0.0. It doesn't happen with 4.6.0.0. Note these are I get a bunch of exceptions that look like this:
|
Crash reported in issue spotbugs#608
@archiecobbs I think your issue was a duplicate of #2041 and was fixed in 4.7.1 by #2054 |
@gtoison thanks for the pointer. |
* test: reproducer for crash in redundant condition assertion Crash reported in issue #608 * fix: calculate the end position of the assert block by finding ATHROW
The issue is recreated and fixed in #2887. |
I'm getting a lot of the same exception:
MyTroublesomeClassToAnalyze is not the only class for which this is a problem. Other classes throw the same exception, just with different indices for the IndexOutOfBoundsException:
Each of these classes extends a common base class, so they do have that in common.
The text was updated successfully, but these errors were encountered: