Need more logs from SCR
-----------------------
Key: FELIX-639
URL: https://issues.apache.org/jira/browse/FELIX-639
Project: Felix
Issue Type: Improvement
Components: Declarative Services (SCR)
Affects Versions: scr-1.0.2
Environment: linux
Reporter: Pierre De Rop
Priority: Minor
As explained in the dev post
http://www.mail-archive.com/[email protected]/msg05030.html,
I would like the SCR to be improved in order to log some WARNINGs, when a
SCR.xml descriptor contains invalid elements, event if it is well formed.
for example, the following SCR.xml has two errors:
<components>
<component name="Component1">
<implementation class="test.ds.hello.HelloComponent1"/>
<reference name="LOG" interface="org.osgi.service.log.LogService"
bind="setLog"
unbind="unsetLog"
cardinality="1..n"
policy="dynamic"/>
</component>
<component name=""Component2">
<implementation class="test.ds.hello.HelloComponent2"/>
<reference name="LOG" interface="org.osgi.service.log.LogService"
bind="setLog"
unbind="unsetLog"
cardinality="1..n"
policy="dynamic"/>
<reference name="LOG" interface="org.osgi.service.log.LogService"
bind="setLog2"
unbind="unsetLog2"
cardinality="1..n"
policy="dynamic"/>
</component>
</components>
-> the two components are embedded in an invalid <components> xml root element
-> the component "Component2" has two references with the SAME name
I would like the SCR to log some WARNINGs message, when finding these sort of
errors:
1/ log a WARNING message when finding an unknown/invalid xml element
2/ log a WARNING message when duplicate reference names are detected for one
given component.
Here is a tentative fix which is working for my use cases:
1/ in the org.apache.felix.scr.impl.ComponentMetadata.validate() method
(around line 299):
// Check that the references are ok.
// We'll especially Check if there's not duplicate names in the
component references.
HashSet refs = new HashSet();
Iterator referenceIterator = m_references.iterator();
while ( referenceIterator.hasNext() )
{
ReferenceMetadata refMeta = ( ReferenceMetadata )
referenceIterator.next();
refMeta.validate( this );
if (! refs.add(refMeta.getName())) {
throw validationFailure( "Detected duplicate reference name: \""
+ refMeta.getName() + "\"");
}
}
2/ in org.apache.felix.scr.impl.XmlHandler.startElement method (around line
215, at the end of the method):
+++ src/main/java/org/apache/felix/scr/impl/XmlHandler.java (working copy)
@@ -211,14 +211,21 @@
ref.setUnbind( attrib.getProperty( "unbind" ) );
m_currentComponent.addDependency( ref );
- }
+ }
+ else {
+ throw new ParseException("Invalid SCR xml element found in
" + m_bundle.getLocation() +
+ ": \"" + localName + "\"", null);
+ }
}
catch ( Exception ex )
{
ex.printStackTrace();
throw new ParseException( "Exception during parsing", ex );
}
- }
+ } else {
+ throw new ParseException("Invalid SCR xml element found in " +
m_bundle.getLocation() +
+ ": \"" + localName + "\"", null);
+ }
}
-> Here is the complete/modifed method:
public void startElement( String uri, String localName, Properties attrib )
throws ParseException
{
// according to the spec, the elements should have the namespace,
// except when the root element is the "component" element
// So we check this for the first element, we receive.
if ( firstElement )
{
firstElement = false;
if ( localName.equals( "component" ) && "".equals( uri ) )
{
overrideNamespace = NAMESPACE_URI;
}
}
if ( overrideNamespace != null && "".equals( uri ) )
{
uri = overrideNamespace;
}
if ( NAMESPACE_URI.equals( uri ) )
{
try
{
// 112.4.3 Component Element
if ( localName.equals( "component" ) )
{
// Create a new ComponentMetadata
m_currentComponent = new ComponentMetadata();
// name attribute is mandatory
m_currentComponent.setName( attrib.getProperty( "name" ) );
// enabled attribute is optional
if ( attrib.getProperty( "enabled" ) != null )
{
m_currentComponent.setEnabled( attrib.getProperty(
"enabled" ).equals( "true" ) );
}
// immediate attribute is optional
if ( attrib.getProperty( "immediate" ) != null )
{
m_currentComponent.setImmediate( attrib.getProperty(
"immediate" ).equals( "true" ) );
}
// factory attribute is optional
if ( attrib.getProperty( "factory" ) != null )
{
m_currentComponent.setFactoryIdentifier(
attrib.getProperty( "factory" ) );
}
// Add this component to the list
m_components.add( m_currentComponent );
}
// 112.4.4 Implementation
else if ( localName.equals( "implementation" ) )
{
// Set the implementation class name (mandatory)
m_currentComponent.setImplementationClassName(
attrib.getProperty( "class" ) );
}
// 112.4.5 [...] Property Elements
else if ( localName.equals( "property" ) )
{
PropertyMetadata prop = new PropertyMetadata();
// name attribute is mandatory
prop.setName( attrib.getProperty( "name" ) );
// type attribute is optional
if ( attrib.getProperty( "type" ) != null )
{
prop.setType( attrib.getProperty( "type" ) );
}
// 112.4.5: If the value attribute is specified, the body
of the element is ignored.
if ( attrib.getProperty( "value" ) != null )
{
prop.setValue( attrib.getProperty( "value" ) );
m_currentComponent.addProperty( prop );
}
else
{
// hold the metadata pending
m_pendingProperty = prop;
}
}
// 112.4.5 Properties [...] Elements
else if ( localName.equals( "properties" ) )
{
readPropertiesEntry( attrib.getProperty( "entry" ) );
}
// 112.4.6 Service Element
else if ( localName.equals( "service" ) )
{
m_currentService = new ServiceMetadata();
// servicefactory attribute is optional
if ( attrib.getProperty( "servicefactory" ) != null )
{
m_currentService.setServiceFactory( attrib.getProperty(
"servicefactory" ).equals( "true" ) );
}
m_currentComponent.setService( m_currentService );
}
else if ( localName.equals( "provide" ) )
{
m_currentService.addProvide( attrib.getProperty(
"interface" ) );
}
// 112.4.7 Reference element
else if ( localName.equals( "reference" ) )
{
ReferenceMetadata ref = new ReferenceMetadata();
ref.setName( attrib.getProperty( "name" ) );
ref.setInterface( attrib.getProperty( "interface" ) );
// Cardinality
if ( attrib.getProperty( "cardinality" ) != null )
{
ref.setCardinality( attrib.getProperty( "cardinality" )
);
}
if ( attrib.getProperty( "policy" ) != null )
{
ref.setPolicy( attrib.getProperty( "policy" ) );
}
//if
ref.setTarget( attrib.getProperty( "target" ) );
ref.setBind( attrib.getProperty( "bind" ) );
ref.setUnbind( attrib.getProperty( "unbind" ) );
m_currentComponent.addDependency( ref );
}
else {
throw new ParseException("Invalid SCR xml element found in
" + m_bundle.getLocation() +
": \"" + localName + "\"", null);
}
}
catch ( Exception ex )
{
ex.printStackTrace();
throw new ParseException( "Exception during parsing", ex );
}
} else {
throw new ParseException("Invalid SCR xml element found in " +
m_bundle.getLocation() +
": \"" + localName + "\"", null);
}
}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.