Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden
+49 (0) 351/8 33 82-0

Workaround für Bug im Trigger Modultyp

Seit Con­flu­ence 2.10 gibt es einen ziem­lich unan­ge­neh­men Bug im Trig­ger-Plugin-Modul­typ:

Manch­mal kommt es vor, dass ein Plugin bei der Instal­la­tion nicht erfolg­reich akti­viert wer­den kann. In die­sem Fall wer­den alle Module deak­ti­viert, also auch der Trig­ger. Dabei wird aber auch ver­sucht den zuge­hö­ri­gen Job zu deak­ti­vie­ren. Ist der zu dem Zeit­punkt noch nicht voll­stän­dig gela­den, kommt es zu einer Ille­gal­Sta­te­Ex­cep­tion. In der Folge befin­det sich das Plugin in einer Art “Zwi­schen­zu­stand”. Es erscheint zwar als instal­liert und akti­viert in der Plugin­über­sicht, aber keine der vom Plugin bereit­ge­stellt Funk­tio­nen sind ver­füg­bar. Außer­dem kann das Plugin erst nach einem Neu­start von Con­flu­ence aus dem Sys­tem ent­fernt wer­den. Jeder Ver­such es ohne Neu­start zu deinstal­lie­ren wird mit einer org.springframework.orm.ObjectRetrievalFailureException quit­tiert.

Da die­ses Pro­blem die War­tung von Kun­den­in­stal­la­tio­nen und Nightly Builds erheb­lich erschwert, mus­ste ein Work­a­round her. Da es seit Con­flu­ence 2.10 die Mög­lich­keit gibt eigene Plugin Modul­ty­pen zu defi­nie­ren indem man den neuen Module-Type-Modul­typ ver­wen­det, war es rela­tiv ein­fach eine Lösung zu fin­den, die sogar als Plugin instal­liert wer­den kann (keine Anpas­sung des Con­flu­ence Kerns nötig!): Man defi­niert einen Modul­typ, der von Trig­ger­Mo­du­le­De­scrip­tor (der Imple­me­ta­tion des Trig­ger-Plugin-Modul­typs) erbt. Dort über­schreibt man die Methode disa­b­led(), deren Auf­ruf die Excep­tion ver­ur­sacht:

 public class RobustTriggerModuleDescriptor extends TriggerModuleDescriptor { /** * Logger for this class. */ static Logger LOG = Logger.getLogger(RobustTriggerModuleDescriptor.class); static final String WARN_MESSAGE = "Using workaround for CONF-14828. "+ "Code might be deprecated."; static final String ERROR_MESSAGE = "Disabling of module failed."; public void init(final Plugin plugin, final Element element) throws PluginParseException { Scheduler sched = (Scheduler) ContainerManager.getComponent("scheduler"); setScheduler(sched); super.init(plugin, element); } /** * {@inheritDoc} */ @Override public void disabled() { try { super.disabled(); } catch (IllegalStateException e) { LOG.warn(WARN_MESSAGE); try { // using reflection to replicate behavior of // AbstractModuleDescriptor.disabled() // as the call to this method was suppressed by // the exception and there is no way // to call super.super.disabled() Field enabledField = AbstractModuleDescriptor.class .getDeclaredField("enabled"); enabledField.setAccessible(true); enabledField.set(this, false); Field moduleClassField = AbstractModuleDescriptor.class .getDeclaredField("moduleClass"); moduleClassField.setAccessible(true); moduleClassField.set(this, null); } catch (Exception e1) { LOG.error(ERROR_MESSAGE, e1); } } } }

Die Methode init() wurde über­schrie­ben um die vom Trig­ger benö­tigte Sche­du­ler-Bean zu inji­zie­ren. Im Trig­ger­Mo­du­le­De­scrip­tor wird diese Bean durch Auto­wiring auto­ma­ti­sch gesetzt. Da der abge­lei­tete Robust­Trig­ger­Mo­du­le­De­scrip­tor aber ein ande­rer Modul­typ ist, fin­det bei des­sen Initia­li­sie­rung kein Auto­wiring statt.

Um den neuen Modul­typ nut­zen zu kön­nen, muss man ihn zunächst im Plugin-Descrip­tor (atlassian-plugin.xml) kon­fi­gu­rie­ren:

<module-type name="Robust Trigger Module Descriptor" key="robust-trigger" class="your.fancy.package.name.RobustTriggerModuleDescriptor"/>

Nun kann man den neuen Modul­typ anstelle des Stan­dard-Trig­gers ver­wen­den:

<robust-trigger key="uniqueKey" name="My Trigger" > <job key="myJob" /> <schedule cron-expression="0 0 * * * ?" /> </robust-trigger>

Dabei ist zu beach­ten, dass in Con­flu­ence 2.10 die Defi­ni­tion und die Ver­wen­dung des neuen Modul­typs nicht in dem sel­bem Plugin erfol­gen dür­fen. Das geht erst ab Con­flu­ence 3.0.

1 Kommentar

Work­a­round für CONF-14828: http://bit.ly/3KkH2B. Ich liebe Reflec­tion
This com­ment was ori­gi­nally pos­ted on Twit­ter

Kommentar hinterlassen