Difference of property definition in component.xml (OSGI DS) - java

Could someone tell me the difference between this two property definitions?
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="blablaService">
<property name="dbUrl" type="String">jdbc:h2:url</property>
<property name="dbUser" type="String" value="user" />
</scr:component>
I'm using Dictionary properties = context.getProperties(); to get the values. It seems to be that if the property given surround with xxx is treated as an Object holding a String[1] and the property which value is specified in the value attribute is treated as an Object which is de facto a String. For the first example (String) throws and Exception as the latter does not.
I'm developing using Eclipse and the Component Context is from org.osgi.service.component.ComponentContext.

<property name="dbUser" type="String" value="user" /> yields a scalar String.
<property name="dbUrl" type="String">jdbc:h2:url</property> yields a String[1].
This is per the spec. See 112.4.6 in the Compendium Spec.

Related

BeanIO writes 0 instead of intended value

I have a fixed-length stream containing record counters
Records starts with Z
Characters 16+9 (human form) contain B record counter
Characters 25+9 (human form) contain C record counter
All numbers padded with 0 and aligned to the right
Record ends with A + CRLF at position 1898 (record is long 2000 chars)
Following BeanIO mapping code
<record name="RECORD_Z" class="com.acme.ftt2017.RecordZ" order="4" minOccurs="1" maxOccurs="1" maxLength="1900">
<field name="tipoRecord" rid="true" at="0" ignore="true" required="true" length="1" lazy="true" literal="Z" />
<field name="numeroRecordB" at="15" length="9" padding="0" align="right" trim="true" />
<field name="numeroRecordC" at="24" length="9" padding="0" align="right" trim="true" />
<field name="terminatorA" at="1897" length="1" rid="true" literal="A" ignore="true" />
</record>
Bean
public class RecordZ implements Serializable
{
private final char tipoRecord = 'Z';
private Integer numeroRecordB, numeroRecordC;
// G & S omitted
}
I have triple-checked in debug the following code:
RecordZ trailer = new RecordZ();
trailer.setNumeroRecordB(1);
trailer.setNumeroRecordC(countRecordC); // equals 1 in debug
log.debug("Exporting record Z");
log.trace("Record Z: " + trailer.toString());
exporter.write(FttRecordTypes.RECORDTYPE_FTT_Z, trailer);
However the produced data file contains the following
Z 000000000000000000 A
Expected
Z 000000001000000001 A
What is wrong with my export code? Why am I getting always zeroes?
From the last paragraph in Section 4.3.1
Optionally, a format attribute can be used to pass a decimal format for java.lang.Number types, and for passing a date format for java.util.Date types. In the example below, the hireDate field uses the SimpleDateFormat pattern "yyyy-MM-dd", and the salary field uses the DecimalFormat pattern "#,##0". For more information about supported patterns, please reference the API documentation for Java's java.text.DecimalFormat and java.text.SimpleDateFormat classes.
And in Section 4.3.2
A type handler may be explicitly named using the name attribute, and/or registered for all fields of a particular type by setting the type attribute. The type attribute can be set to the fully qualified class name or type alias of the class supported by the type handler. To reference a named type handler, use the typeHandler field attribute when configuring the field.
Thus, You can try one of 2 things:
Remove the use of your custom *IntegerTypeHandlers and specify a format attribute on the fields which use these custom type handlers. This might be a lot of work depending on the amount of fields and type handlers you have. For example:
<field name="numeroRecordB" format="000000000" at="15" length="9" padding="0" align="right" trim="true" />
OR
Make the getType() method return null instead of Integer.class in your custom type handlers, this will hopefully then not be used as a global type handler. I haven't done this before, so it might not work.
public Class<?> getType() {
return null;
}
Hope this helps.
Discovered the guilty. The custom type handlers!!!!
According to BeanIO
A type handler may be explicitly named using the name attribute, and/or registered for all fields of a particular type by setting the type attribute. The type attribute can be set to the fully qualified class name or type alias of the class supported by the type handler. To reference a named type handler, use the typeHandler field attribute when configuring the field.
So I did not show that in the heading of my file I have registered plenties of custom type handlers, unfortunately all with a type attribute.
<typeHandler name="int_2" type="java.lang.Integer" class="org.beanio.types.IntFixedLengthTypeHandler">
<property name="numberOfDigits" value="2" />
</typeHandler>
<typeHandler name="int_4" type="java.lang.Integer" class="org.beanio.types.IntFixedLengthTypeHandler">
<property name="numberOfDigits" value="2" />
</typeHandler>
<typeHandler name="int_10" type="java.lang.Integer" class="org.beanio.types.IntFixedLengthTypeHandler">
<property name="numberOfDigits" value="10" />
</typeHandler>
<typeHandler name="bigint_16" type="java.math.BigInteger" class="org.beanio.types.BigIntFixedLengthTypeHandler">
<property name="numberOfDigits" value="16" />
</typeHandler>
Removing the type attribute works

How to Parse XML Document By Class Name Using Java

I'm writing a parsing tool to compare the textual content of two bean XML files in Java. The text content changes and we need a way to run a script to make sure the textual content is the same. I know we have org.w3c.dom which has a method getElementsByTagName("tag_name") and that returns a node list in the XML document. I'm wondering if anyone knows of a way to do this using the class name? I've been searching around but haven't been able to solve this yet.
<bean class="com.mycompany.myText" id="Q1.4">
<property name="name">
<value>Q1.4</value>
</property>
<property name="text">
<value>This is text one</value>
</property>
<property name="retired">
<value>true</value>
</property>
</bean>
<bean class="com.mycompany.myText" id="Q1.5">
<property name="name">
<value>Q1.5</value>
</property>
<property name="text">
<value>This is text two</value>
</property>
<property name="retired">
<value>true</value>
</property>
</bean>
I can't use the 'bean' element name as there are several other beans whith non relevant stuff I need only the ones with the class com.mycompany.myText and the value I'm trying to extract is property name=text - the text content
Any help here would be appreciated. Also as a side note I should mention that we have no direct control of how the XML file is managed and structured as it's fed to us from a 3rd party.
As you say, you need to select tags by their attributes.
You could use XPath to achieve this. See those resources:
http://viralpatel.net/blogs/java-xml-xpath-tutorial-parse-xml/
https://stackoverflow.com/a/24220968/6377268
The expression would be something like this
/bean[#class='com.mycompany.myText']/property[#name='text']/value
I hope I could help at least a little bit.

How does Spring convert a String into an array?

I have a standard Spring class that accepts a String array. I know that Spring will take care of splitting a comma separated String into an array, but I'm unaware of how it does it under the hood.
The question that led me to this is whether the Strings will become trimmed after being split, but I would like to know how to see this under the hood activity as well if other future issues arise.
<bean id="allServicersDelimitedLineTokenizer"
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="col1,col2,col3,col4" />
</bean>
is the same as?
<bean id="allServicersDelimitedLineTokenizer"
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="col1 , col2, col3, col4" />
</bean>

MySQL/Hibernate : Default value for not-null column does not work

org.hibernate.PropertyValueException: not-null property references a
null or transient value
I am using Java,Hibernate and MySQL 5.1.52-log version.
My interpretation of default is if I don't supply value for the column, Hibernate will insert the default value when I try to save this object.
HBM file,
<property name="isActive" type="java.lang.Short">
<column name="IsActive" not-null="true" default="1"/>
</property>
According to the documentation of PropertyValueException, if you set a null value in a property declared not-null="true" and then try to persist/update it, then you will get this exception.
See http://docs.jboss.org/hibernate/orm/3.5/javadoc/org/hibernate/PropertyValueException.html
You should remove the not-null="true" attribute from the config (because the default value of not-null is false) and then the database should insert the default value that you specified in the configuration for you (in this case '1').
[UPDATE]
I would have preferred to put this as a comment in fujy's answer but I am not allowed to comment on other answers yet. Does it work as expected if you remove the 'not-null' attribute (As I am showing below)? I believe that is what is causing the exception that you are getting.
<property name="isActive" type="java.lang.Short">
<meta attribute="default-value">1</meta>
<column name="IsActive" />
</property>
You could simply set it on your model directly
private Short isActive = 1;
Or you could try this in your hbm file
<property name="isActive" type="java.lang.Short">
<meta attribute="default-value">1</meta>
<column name="IsActive" not-null="true"/>
</property>

Why would Spring be trying to use the properties variable reference string instead of the value?

Here's the problem in a nutshell:
<bean id="handlerFactory" class="com.westfieldgrp.audit.jdklogging.cpm.CPMHandlerFactory">
<property name="schemaName" value="${env.audit.databaseSchema}" />
<property name="bufferSize" value="${env.audit.bufferSize}" />
<property name="threaded" value="${env.audit.threadedAuditHandler}" />
<property name="dataSourceSelector" ref="dataSourceSelector" />
</bean>
bufferSize on the CPMHandlerFactory is an int. Spring is failing because it is trying to set the value to '${env.audit.bufferSize}' instead of the actual value from the properties file.
Now, when I change the name of the properties file or env.audit.bufferSize in the file, Spring complains that it can't find the property 'env.audit.bufferSize'. This says to me that it CAN find the property, but instead of setting the value to '20', it's trying to set it to '${env.audit.bufferSize}'. Can anyone explain why Spring might be doing this and what I can do about it?
Contents of the properties file below:
env.audit.databaseSchema=TDB2DATA
env.audit.dataSourceName=java:comp/env/AuditDataSourceAlias
env.audit.bufferSize=20
env.audit.threadedAuditHandler=true
Thanks,
Peter
EDIT:
Found the problem thanks to Jamestastic below. Here's what it was:
We have a "master" context file that looks like so:
<import resource="environmentBeans.xml" />
<import resource="serviceBeans.xml" />
<import resource="auditBeans.xml" />
The 'environmentBeans.xml' has the PropertyPlaceholderConfigurer in it. The problem was, I added some code that referenced the 'auditBeans.xml' context, which of course doesn't have the configurer. I switched it to reference the 'master' context and it works great.
The key was understanding why the values wouldn't get substituted out: because there was no property configurer.
So, Thanks!
Did you remember to add <context:property-placeholder /> or a PropertyPlaceholderConfigurer bean definition to your Spring context?

Categories

Resources