Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 15C8C17CB9 for ; Tue, 14 Jul 2015 13:25:58 +0000 (UTC) Received: (qmail 86805 invoked by uid 500); 14 Jul 2015 13:25:51 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 86765 invoked by uid 500); 14 Jul 2015 13:25:51 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 86756 invoked by uid 99); 14 Jul 2015 13:25:51 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 14 Jul 2015 13:25:51 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id A4132AC0323 for ; Tue, 14 Jul 2015 13:25:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1690926 - in /felix/trunk/scr/src: main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java Date: Tue, 14 Jul 2015 13:25:51 -0000 To: commits@felix.apache.org From: davidb@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150714132551.A4132AC0323@hades.apache.org> Author: davidb Date: Tue Jul 14 13:25:51 2015 New Revision: 1690926 URL: http://svn.apache.org/r1690926 Log: [SCR] Fix potential NPE in concurrent scenarios Also included unit tests. Added: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java?rev=1690926&r1=1690925&r2=1690926&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java Tue Jul 14 13:25:51 2015 @@ -450,7 +450,7 @@ public class SingleComponentManager e { servicePids.addAll((List)configPropServicePids); } - else + else { servicePids.add(configPropServicePids.toString()); } @@ -458,7 +458,7 @@ public class SingleComponentManager e { servicePids.add((String)m_factoryProperties.get(Constants.SERVICE_PID)); } - + if ( servicePids.size() == 1 ) { props.put(Constants.SERVICE_PID, servicePids.get(0)); @@ -761,10 +761,11 @@ public class SingleComponentManager e public S getService( Bundle bundle, ServiceRegistration serviceRegistration ) { boolean success = getServiceInternal(); - if ( success ) + ComponentContextImpl componentContext = m_componentContext; + if ( success && componentContext != null) { m_useCount.incrementAndGet(); - return m_componentContext.getImplementationObject( true ); + return componentContext.getImplementationObject( true ); } else { Added: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java?rev=1690926&view=auto ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java (added) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java Tue Jul 14 13:25:51 2015 @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.felix.scr.impl.manager; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import java.lang.reflect.Field; + +import org.apache.felix.scr.impl.config.ComponentContainer; +import org.apache.felix.scr.impl.helper.ComponentMethods; +import org.apache.felix.scr.impl.metadata.ComponentMetadata; +import org.apache.felix.scr.impl.metadata.DSVersion; +import org.junit.Test; +import org.mockito.Mockito; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +public class SingleComponentManagerTest +{ + @Test + public void testGetService() throws Exception { + ComponentMetadata cm = new ComponentMetadata(DSVersion.DS13); + cm.setImplementationClassName("foo.bar.SomeClass"); + cm.validate(null); + + @SuppressWarnings("unchecked") + ComponentContainer cc = Mockito.mock(ComponentContainer.class); + Mockito.when(cc.getComponentMetadata()).thenReturn(cm); + + SingleComponentManager scm = new SingleComponentManager(cc, new ComponentMethods()) { + @Override + boolean getServiceInternal() + { + return true; + } + }; + + BundleContext bc = Mockito.mock(BundleContext.class); + Bundle b = Mockito.mock(Bundle.class); + Mockito.when(b.getBundleContext()).thenReturn(bc); + + ComponentContextImpl cci = new ComponentContextImpl(scm, b); + Object implObj = new Object(); + cci.setImplementationObject(implObj); + cci.setImplementationAccessible(true); + + Field f = SingleComponentManager.class.getDeclaredField("m_componentContext"); + f.setAccessible(true); + f.set(scm, cci); + + scm.m_internalEnabled = true; + assertSame(implObj, scm.getService(null, null)); + } + + @Test + public void testGetServiceWithNullComponentContext() + { + ComponentMetadata cm = new ComponentMetadata(DSVersion.DS13); + cm.setImplementationClassName("foo.bar.SomeClass"); + cm.validate(null); + + @SuppressWarnings("unchecked") + ComponentContainer cc = Mockito.mock(ComponentContainer.class); + Mockito.when(cc.getComponentMetadata()).thenReturn(cm); + + SingleComponentManager scm = new SingleComponentManager(cc, new ComponentMethods()) { + @Override + boolean getServiceInternal() + { + return true; + } + }; + scm.m_internalEnabled = true; + assertNull("m_componentContext is null, this should not cause an NPE", + scm.getService(null, null)); + } +}