cancel
Showing results for 
Search instead for 
Did you mean: 

Use of PropertyPlaceholderConfigurer in Alfresco Modules

darryl_staflund
Champ in-the-making
Champ in-the-making
Hi there,

I have spent the last couple of days moving some important configuration values out of the Spring context modules of my Alfresco AMPs into some property files.  But when I try to make use of them using a PropertyPlaceholderConfigurer bean, the values defined in the files aren't found.  I am not sure what's going on here.  Why don't these beans make the values defined in my property files available to Spring when it's processing the context file?

For example, in one AMP that I've created, I have moved the following configuration values into a property file:


#   Frequency of Minor Correction Workflow report.
my_module_id.job.workflow_report.minor_correction.cron=0 0/5 * * * ? *

#   Frequency of Final Author Review Workflow report.
my_module_id.job.workflow_report.final_author_review.cron=0 0/5 * * * ? *

#   Frequency of Minor / Exam Revision Workflow report.
my_module_id.job.workflow_report.minor_exam_revision.cron=0 0/5 * * * ? *

#   Frequency of Records Management Audit report.
my_module_id.job.rm_audit_report.cron=0 0/2 * * * ?

#   Should Minor Correction Request workflow be re-deployed on application start-up?
#   Will result in new versions of the workflow being created in Alfresco.
#
#      Dev Environments = true
#      QA Environments = true
#      UAT Environments = true
#      Staging Environments = false
#      Production = false
my_module_id.workflow.minor_correction_request.model.reploy_on_startup=true

#   Should Final Author Review workflow be re-deployed on application start-up?
#   Will result in new versions of the workflow being created in Alfresco.
#
#      Dev Environments = true
#      QA Environments = true
#      UAT Environments = true
#      Staging Environments = false
#      Production = false
my_module_id.workflow.final_author_review.model.reploy_on_startup=true

#   Should Minor / Exam Revision workflow be re-deployed on application start-up?
#   Will result in new versions of the workflow being created in Alfresco.
#
#      Dev Environments = true
#      QA Environments = true
#      UAT Environments = true
#      Staging Environments = false
#      Production = false
my_module_id.workflow.minor_exam_revision.model.reploy_on_startup=true

#   Maximum number of courses to display in My Courses dashlet at any one time.
#   The smaller the value, the greater the performance.
my_module_id.dashlet.courses.max_items=25

#   The name of the Alfresco datalist used to generate the RM Audit Report.
#   Should never need to be changed.
my_module_id.rm.audit.datalist=Records Management Change Log

I then substitute reference their values in beans that look like this:


    <!–
        #############################################################################
        Job:            Workflow Summary Report (Minor Correction)
        Description:    Generates a DCMP workflow summary report.
        #############################################################################
    –>
    <bean id="requestMinorCorrectionActivityReportJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
        <property name="jobClass" value="my.package.bi.components.report.jobs.WorkflowActivityReport" />
        <property name="jobDataAsMap">
            <map>
                <entry key="callbackCommand" value-ref="workflowActivityReportCallbackCommand" />
                <entry key="transactionService" value-ref="TransactionService" />
                <entry key="workflowModel">
                    <util:constant static-field="my.package.common.models.wf.DcmpWorkflowModel.MinorCorrection" />
                </entry>
            </map>
        </property>
    </bean>
       
    <bean
        id="requestMinorCorrectionActivityReportTrigger"
        class="org.alfresco.util.CronTriggerBean"
        depends-on="module_id_1.modelBootstrap">
        <property name="jobDetail" ref="requestMinorCorrectionActivityReportJobDetail" />
        <property name="scheduler" ref="schedulerFactory" />
        <property name="cronExpression" value="${my_module_id.job.workflow_report.minor_correction.cron}" />
    </bean>

and then read the properties into Spring using the following bean:


    <bean id="module_id_properties" parent="common-placeholder-configurer">
        <property name="ignoreUnresolvablePlaceholders" value="false" />
        <property name="properties" ref="global-properties" />
        <property name="localOverride" value="false" />
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_NEVER" />
        <property name="locations">
            <list>
                <value>classpath:alfresco/module/module_id/module_id.properties</value>
            </list>
        </property>
    </bean>   

In my mind this should work.  But when I start Alfresco, I get an error due to the fact that Spring has not substituted '${}' property references with the corresponding values.

What am I doing wrong?

Thanks,
Darryl
3 REPLIES 3

hap234
Champ in-the-making
Champ in-the-making
Check the key that you have give in property file.
my_module_id.job.workflow_report.minor_correction.cron=0 0/5 * * * ? *

And check the key that you have given in Spring bean reference.

<property name="cronExpression" value="${my.package.job.workflow_report.minor_correction.cron}"

I think both are different which is the cause of this issue.
change either one to make it same as other will solve your problem.

Best Regards,
Hetal Patel,
CIGNEX Tech

darryl_staflund
Champ in-the-making
Champ in-the-making
Hi Hetal,

Thanks for bringing the typo to my attention – it's not part of the code but was introduced when I anonymized my config values for display in the forum.  I didn't catch the discrepancy.  Sorry about that.  It should be fixed now.

The problem remains though – Spring doesn't substitute property references with values read by the PropertyPlaceholderConfigurer class.

Darryl

darryl_staflund
Champ in-the-making
Champ in-the-making
Hi everyone,

I have figured out how to read spring configuration properties on a project-by-project basis.  It turns out that every PropertyPlaceholderConfigurer bean defined in a Spring application has to have a unique placeholder Prefix/Suffix combination – meaning that if you define two or more configurer beans using ${} as your placeholder syntax, only the values read by one of the beans will be used.  This is why Alfresco kept throwing an exception when trying to process my bean definitions – it couldn't find the properties defined by my configurer bean because the placeholder syntax was mapped to another bean.

I was able to get it working using the following configurer bean:


    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:alfresco/module/module_id/module_id.properties" />
        <property name="placeholderPrefix" value="%{module_id:" />
        <property name="placeholderSuffix" value="}" />
    </bean>

and the following placeholder references:


    <bean id="module_id_maxVersionPolicy" class="company.id.alfresco.common.policies.MaxVersionPolicy" init-method="init">
        <property name="maxVersionPolicyCandidateSpecification" ref="module_id_maxVersionPolicyCandidateSpecification" />
        <property name="policyComponent" ref="policyComponent" />
        <property name="versionService" ref="versionService" />
        <property name="maxVersions" value="%{module_id:policy.document_versioning.maxVersions}" />
    </bean>

My resource file looks as follows:


policy.document_versioning.maxVersions=10

Note that '${module:' won't work as a prefix because the '${' portion of the prefix causes Spring to map it to another configurer defined somewhere else in Alfresco.  I don't use '#{' so as not to conflict with JSF.  Since I have more than one module to support, I include the module id in the placeholder prefix.

I hope this is helpful to someone.

Darryl