Sonar Fixes

https://sonar.spring.io/component_issues?id=org.springframework.integration%3Aspring-integration%3Amaster#resolved=false|types=BUG

In `IntegrationFlowRegistration` double check locking is ok for `inputChannel`
because we're assigning an existing object, but `MessagingTemplate` constructs
a new object for which double check locking doesn't work.

In any case, for both these items, the chance of concurrent access is extremely low
and is idempotent anyway, so remove double check locking.

Several inner classes can be static.

Other minor fixes.
This commit is contained in:
Gary Russell
2016-11-18 13:34:17 -05:00
committed by Artem Bilan
parent 1bba73fc06
commit f070de0b7e
20 changed files with 63 additions and 64 deletions

View File

@@ -229,7 +229,7 @@ public class DefaultHeaderChannelRegistry extends IntegrationObjectSupport
}
private final class MessageChannelWrapper {
private static final class MessageChannelWrapper {
private final MessageChannel channel;

View File

@@ -119,7 +119,7 @@ public class QueueChannel extends AbstractPollableChannel implements QueueChanne
long nanos = TimeUnit.MILLISECONDS.toNanos(timeout);
long deadline = System.nanoTime() + nanos;
while (this.queue.size() == 0 && nanos > 0) {
this.queueSemaphore.tryAcquire(nanos, TimeUnit.NANOSECONDS);
this.queueSemaphore.tryAcquire(nanos, TimeUnit.NANOSECONDS); // NOSONAR - ok to ignore result
nanos = deadline - System.nanoTime();
}
return this.queue.poll();

View File

@@ -84,7 +84,7 @@ public class ServiceActivatorAnnotationPostProcessor extends AbstractMethodAnnot
return serviceActivator;
}
private final class ReplyProducingMessageHandlerWrapper extends AbstractReplyProducingMessageHandler
private static final class ReplyProducingMessageHandlerWrapper extends AbstractReplyProducingMessageHandler
implements Lifecycle {
private final MessageHandler target;

View File

@@ -35,7 +35,7 @@ public class StandardIntegrationFlow implements IntegrationFlow, SmartLifecycle
private final List<SmartLifecycle> lifecycles = new LinkedList<SmartLifecycle>();
private final boolean registerComponents = true;
private final boolean registerComponents = true; // NOSONAR
private boolean running;
@@ -43,7 +43,7 @@ public class StandardIntegrationFlow implements IntegrationFlow, SmartLifecycle
this.integrationComponents = new LinkedList<Object>(integrationComponents);
}
//TODO Figure out some custom DestinationResolver when we don't register singletons
//TODO Figure out some custom DestinationResolver when we don't register singletons - remove NOSONAR above when done
/*public void setRegisterComponents(boolean registerComponents) {
this.registerComponents = registerComponents;
}*/

View File

@@ -53,7 +53,7 @@ public class IntegrationFlowRegistration {
}
void setBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
this.beanFactory = beanFactory; // NOSONAR (synchronization)
}
void setIntegrationFlowContext(IntegrationFlowContext integrationFlowContext) {
@@ -78,28 +78,24 @@ public class IntegrationFlowRegistration {
public MessageChannel getInputChannel() {
if (this.inputChannel == null) {
synchronized (this) {
if (this.inputChannel == null) {
if (this.integrationFlow instanceof StandardIntegrationFlow) {
StandardIntegrationFlow integrationFlow = (StandardIntegrationFlow) this.integrationFlow;
Object next = integrationFlow.getIntegrationComponents().iterator().next();
if (next instanceof MessageChannel) {
this.inputChannel = (MessageChannel) next;
}
else {
throw new IllegalStateException("The 'IntegrationFlow' [" + integrationFlow + "] " +
"doesn't start with 'MessageChannel' for direct message sending.");
}
}
else {
throw new IllegalStateException("Only 'StandardIntegrationFlow' instances " +
"(e.g. extracted from 'IntegrationFlow' Lambdas) can be used " +
"for direct 'send' operation. " +
"But [" + this.integrationFlow + "] ins't one of them.\n" +
"Consider 'BeanFactory.getBean()' usage for sending messages " +
"to the required 'MessageChannel'.");
}
if (this.integrationFlow instanceof StandardIntegrationFlow) {
StandardIntegrationFlow integrationFlow = (StandardIntegrationFlow) this.integrationFlow;
Object next = integrationFlow.getIntegrationComponents().iterator().next();
if (next instanceof MessageChannel) {
this.inputChannel = (MessageChannel) next;
}
else {
throw new IllegalStateException("The 'IntegrationFlow' [" + integrationFlow + "] " +
"doesn't start with 'MessageChannel' for direct message sending.");
}
}
else {
throw new IllegalStateException("Only 'StandardIntegrationFlow' instances " +
"(e.g. extracted from 'IntegrationFlow' Lambdas) can be used " +
"for direct 'send' operation. " +
"But [" + this.integrationFlow + "] ins't one of them.\n" +
"Consider 'BeanFactory.getBean()' usage for sending messages " +
"to the required 'MessageChannel'.");
}
}
return this.inputChannel;
@@ -115,25 +111,21 @@ public class IntegrationFlowRegistration {
*/
public MessagingTemplate getMessagingTemplate() {
if (this.messagingTemplate == null) {
synchronized (this) {
if (this.messagingTemplate == null) {
this.messagingTemplate = new MessagingTemplate(getInputChannel()) {
this.messagingTemplate = new MessagingTemplate(getInputChannel()) {
@Override
public Message<?> receive() {
return receiveAndConvert(Message.class);
}
@Override
public <T> T receiveAndConvert(Class<T> targetClass) {
throw new UnsupportedOperationException("The 'receive()/receiveAndConvert()' " +
"isn't supported on the 'IntegrationFlow' input channel.");
}
};
this.messagingTemplate.setBeanFactory(this.beanFactory);
@Override
public Message<?> receive() {
return receiveAndConvert(Message.class);
}
}
@Override
public <T> T receiveAndConvert(Class<T> targetClass) {
throw new UnsupportedOperationException("The 'receive()/receiveAndConvert()' " +
"isn't supported on the 'IntegrationFlow' input channel.");
}
};
this.messagingTemplate.setBeanFactory(this.beanFactory);
}
return this.messagingTemplate;
}

View File

@@ -278,13 +278,13 @@ public class SimpleMessageStore extends AbstractMessageGroupStore
throw outOfCapacityException;
}
group = getMessageGroupFactory().create(groupId);
this.groupIdToMessageGroup.putIfAbsent(groupId, group);
this.groupIdToMessageGroup.put(groupId, group);
upperBound = new UpperBound(this.groupCapacity);
for (Message<?> message : messages) {
upperBound.tryAcquire(-1);
group.add(message);
}
this.groupToUpperBound.putIfAbsent(groupId, upperBound);
this.groupToUpperBound.put(groupId, upperBound);
}
else {
upperBound = this.groupToUpperBound.get(groupId);

View File

@@ -141,7 +141,7 @@ public class SimpleMessageConverter implements MessageConverter, BeanFactoryAwar
}
private class DefaultOutboundMessageMapper implements OutboundMessageMapper<Object> {
private static class DefaultOutboundMessageMapper implements OutboundMessageMapper<Object> {
DefaultOutboundMessageMapper() {
super();

View File

@@ -122,18 +122,22 @@ public class SimplePool<T> implements Pool<T> {
* if it was recently reduced and too many items were in use to allow the new size
* to be set.
*/
public int getPoolSize() {
@Override
public synchronized int getPoolSize() {
return this.poolSize.get();
}
@Override
public int getIdleCount() {
return this.available.size();
}
@Override
public int getActiveCount() {
return this.inUse.size();
}
@Override
public int getAllocatedCount() {
return this.allocated.size();
}
@@ -153,6 +157,7 @@ public class SimplePool<T> implements Pool<T> {
* Obtains an item from the pool; waits up to waitTime milliseconds (default infinity).
* @throws MessagingException if no items become available in time.
*/
@Override
public T getItem() {
boolean permitted = false;
try {
@@ -205,6 +210,7 @@ public class SimplePool<T> implements Pool<T> {
/**
* Returns an item to the pool.
*/
@Override
public synchronized void releaseItem(T item) {
Assert.notNull(item, "Item cannot be null");
Assert.isTrue(this.allocated.contains(item),
@@ -234,6 +240,7 @@ public class SimplePool<T> implements Pool<T> {
}
}
@Override
public synchronized void removeAllIdleItems() {
T item;
while ((item = this.available.poll()) != null) {