2016-09-16 3 views
2

В JSR352 1,0 Final §9.3 Batch Properties свойства партии определяется как тип java.lang.String:JSR 352 Как сохранить объект (java.lang.Object) в качестве свойства job?

Пакетные приложения нужен способ, чтобы получить параметры, когда задание инициируется для исполнения. Свойства могут быть определены с помощью артефактов модели пакетного программирования, а затем значения передаются им при запуске задания. Свойства партии - это строковые значения.

И вот пример:

Properties jobProps = new Properties(); 
jobProps.setProperty("props1", "value1"); 
jobProps.setProperty("props2", "value2"); 

// start 
jobOperator.start("myjob", jobProps); 

Однако, мне нужно использовать другие объекты для работы. Это общее «свойство» может быть любым типом объекта, поэтому java.lang.Object. Поэтому я ищу для работы вокруг решения, которое удовлетворяет следующим условиям:

  • Свойство хранится должно быть неизменным, это означает, что когда-то передается в пакетном режиме исполнения, он не будет изменен снова.
  • Свойство должно сохраняться при прекращении работы и может быть повторно использовано при перезапуске задания. (Serializable?)
  • Решение для рабочего процесса не должно зависеть от какой-либо реализации, например. JBeret от JBoss. Потому что я разрабатываю фреймворк, который позволяет пользователю выбирать собственную реализацию JSR 352.

Может ли кто-нибудь помочь?

+0

Единственный способ получить пакетный контейнер, чтобы сохранить что-либо для вас, - это использовать контрольную точку для чтения/записи фрагментов или постоянные пользовательские данные шага. Вы можете перенести что-то на начальном этапе, но это, вероятно, работает только в том случае, если пользователи вашей инфраструктуры не должны выполнять свою собственную полную работу (JSL). Если вы находитесь в среде EE, возможно, вам следует использовать CDI для совместного использования объектов между подающим артефактом и самими артефактами партии. Было бы интересно увидеть, где вы закончите ... –

+0

Спасибо @ScottKurz. Что делает второе предложение? Вы можете что-то перенести ... свою собственную работу (JSL). Вы имеете в виду, что работа (JSL) должна определяться самой картой и не должна быть перезаписана пользователями? Я работаю в команде Hibernate Search в качестве стажера. Наше пакетное задание определяется только Hibernate Search, а не пользователями, поэтому все в порядке. Работа должна работать как на Java EE, так и на Java SE, поэтому, если CDI можно избежать, было бы лучше. Я думаю об использовании класса утилит или фабричного класса. –

ответ

2

Вот идея, которую я имел в виду для вашего прецедента (даже если это похоже на обходной путь).

Вы можете заполнить постоянный объект на протяжении всего жизненного цикла экземпляра задания (т.е. через перезагрузки), введя один или несколько параметров задания в виде пакетных свойств начального шага, а затем используя постоянные пользовательские данные этого начального шага с помощью шага, настроенного с allow-start-if-complete="true", чтобы гарантировать, что шаг всегда выполняется.


Подробно:

JobOperator интерфейс только позволяет передавать параметры задание к пакетному приложению в виде единого java.util.Properties объекта.

Так что да, если работаете обойти это ограничение, используя какое-либо приложение или другой контекст (как CDI будет предоставлять) не является хорошим вариантом, то вы должны были бы сделать что-то вроде сериализации Serializable (или маршала а, JAXB) и установить его как параметр задания.

Так что, считая, что вы собираетесь сериализовать свойство с именем serializedObj, будет ли работа выглядеть так, чтобы определить объект уровня работы, который является постоянным и неизменным?

Начните с "настройки" шаг, как это:

<step id="setup" next="step1" allow-start-if-complete="true"> 
    <batchlet ref="SetupBatchlet"> 
     <properties> 
      <property name="serializedObj" value="#{jobParameters['serializedObj']}" /> 
     </properties> 

с реализацией:

public class SetupBatchlet implements Batchlet, BonusPayoutConstants { 

    @Inject 
    @BatchProperty(name = "serializedObj") 
    private String serializedObjStr; 

    @Inject 
    private JobContext jobCtx; 

    @Inject 
    private StepContext stepCtx; 

    @Override 
    public String process() throws Exception { 

     // 1. See if step persistent user data already exists 
     MyObject myObj = (MyObject) stepCtx.getPersistentUserData(); 

     // 2. If not, deserialize 
     if (myObj == null) { 
      myObj = ... // deserialize "serializedObjStr" 
      // 2a. Persist user data 
      stepCtx.setPersistentUserData(myObj); 
     } 

     // 3. set for use by later steps 
     jobCtx.setTransientUserData(myObj); 

и теперь step1 и более поздние стадии могут сделать:

MyObject myObj = (MyObject) jobCtx.getTransientUserData(); 

Так это MyObject экземпляр постоянный и неизменный. Конфигурация allow-start-if-complete="true" гарантирует, что шаг «setup» всегда выполняется, а JobContext всегда заполняется.

Это может масштабироваться, если вам нужно собрать несколько объектов, хотя может быть уродливым в определенной точке; все еще та же идея может по-прежнему применяться.

+0

Ваша идея отличная. Я не знал о сериализации, прежде чем задавать этот вопрос, и это очень помогает. Мое окончательное решение немного отличается от вашего, я использую 'AbstractJobListener' вместо' Batchlet', поэтому нам не нужен еще один шаг, и пакетное свойство 'serializedObj' все равно может быть введено как ваше предложение для пакетной программы. Конфигурация JSL тоже очень похожа. Другие части работают нормально. –

+1

Рад, что вы нашли это полезным. Если вы используете прослушиватель заданий, но вместо шага настройки/инициализации, мне интересно, какой шаг вы используете для хранения постоянных пользовательских данных? Другим вариантом в общем случае было бы передать одно и то же значение параметра при перезагрузке (что может потребовать, чтобы вы сохраняли это значение или какой-либо объект выдавал это значение из вашей отправляющей среды; если вы в состоянии это сделать, вам не понадобятся данные постоянных пользователей Было бы интересно узнать, что у вас получилось. –

+0

Привет @ScottKurz, я, наконец, успел реализовать весь код. В JBeret (JBoss impl. Of JSR352) кажется, что параметры задания сохраняются автоматически, когда задание (сначала). Так что, если задание перезапускается без параметров, параметры постоянной работы будут использоваться снова. Вот почему я думал, что место десериализации не имеет значения. Но я могу ошибаться. Является ли роль перезапуска задания в том же в WebSphere Batch? –