Jakarta ee JSR352如何将对象(java.lang.object)存储为作业属性?

Jakarta ee JSR352如何将对象(java.lang.object)存储为作业属性?,jakarta-ee,jsr352,Jakarta Ee,Jsr352,在JSR352 1.0最终§9.3批次属性中,批次属性定义为类型java.lang.String: 批处理应用程序需要一种在启动作业执行时接收参数的方法。属性可以由批处理编程模型工件定义,然后在启动作业时将值传递给它们批处理属性是字符串值。 下面是一个例子: Properties jobProps = new Properties(); jobProps.setProperty("props1", "value1"); jobProps.setProperty("props2", "value2

在JSR352 1.0最终§9.3批次属性中,批次属性定义为类型
java.lang.String

批处理应用程序需要一种在启动作业执行时接收参数的方法。属性可以由批处理编程模型工件定义,然后在启动作业时将值传递给它们批处理属性是字符串值。

下面是一个例子:

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

// start
jobOperator.start("myjob", jobProps);
但是,我需要为作业使用其他对象。这个通用“属性”可以是任何对象类型,因此
java.lang.object
。因此,我正在寻找满足以下要求的变通解决方案:

  • 存储的属性应该是不可变的,这意味着一旦传递到批处理运行时,它就不会再被更改
  • 该属性应在作业停止时保留,并可在作业重新启动时重新使用。(可序列化?)
  • 变通解决方案不应依赖于任何实现,例如JBoss的JBeret。因为我正在开发一个框架,它允许用户选择自己的JSR352实现

有人能帮忙吗?

以下是我对您的用例的想法(即使它看起来确实像一个解决方法)

通过注入一个或多个作业参数作为初始步骤的批处理属性,然后使用该初始步骤的持久用户数据和配置为
allow start if complete=“true”
的步骤,可以在作业实例的生命周期内(即跨重新启动)填充持久对象,以确保该步骤始终运行


详细内容:

JobOperator接口仅允许您以单个java.util.Properties对象的形式将作业参数传递给批处理应用程序

因此,是的,如果通过使用某些应用程序或其他上下文(如CDI提供的)来解决此限制不是一个好的选择,那么您必须执行类似序列化可序列化对象(或封送JAXB对象)的操作,并将其设置为作业参数

因此,假设您要序列化名为
serializedObj
的属性,那么为了定义持久不变的作业级对象,作业会是什么样子呢

从如下“设置”步骤开始:

<step id="setup" next="step1" allow-start-if-complete="true">
    <batchlet ref="SetupBatchlet">
        <properties>
            <property name="serializedObj" value="#{jobParameters['serializedObj']}" />
        </properties>  
现在,步骤1和后续步骤可以:

MyObject myObj = (MyObject) jobCtx.getTransientUserData();
所以这个MyObject实例是持久的和不可变的。
allow start if complete=“true”
配置确保始终运行“设置”步骤,并且始终填充作业上下文


如果需要聚合多个对象,则可以进行缩放,尽管在某一点上可能会变得丑陋;同样的想法仍然适用。

让批处理容器为您持久化任何内容的唯一方法是使用块读取器/写入器检查点或步骤的持久化用户数据。您可以在初始步骤中保留某些内容,但这可能仅在您的框架用户不希望自己完成作业(JSL)的情况下才起作用。如果您在EE环境中,可能应该利用CDI在提交工件和批处理工件之间共享对象。我很想知道你的结局…谢谢@ScottKurz。第二句你能坚持什么。。。拥有完整的作业(JSL)。什么意思?你是说作业(JSL)应该由框架本身定义,而不应该被用户覆盖吗?我在Hibernate搜索团队实习。我们的批处理作业仅由Hibernate搜索定义,而不是由用户定义,所以这是可以的。这项工作应该在JavaEE和JavaSE中都能工作,所以如果可以避免CDI,那就更好了。我正在考虑使用实用类或工厂类。你的想法很好。在问这个问题之前,我不知道序列化,这很有帮助。我的最终解决方案与您的有点不同,我使用了
AbstractJobListener
而不是
Batchlet
,因此我们不需要其他步骤,批处理属性
serializedObj
仍然可以作为您对Batchlet的建议注入。JSL配置也非常相似。其他部分工作正常。很高兴你发现这很有帮助。如果您使用的是作业侦听器而不是setup/init步骤,我想知道您使用哪一步来存储持久用户数据?另一个选择是在重启时传递相同的参数值(这可能需要您持久化该值或从您的提交环境中生成该值的任何对象;如果您能够做到这一点,您不需要持久化用户数据这一步骤。我很想看看您最终得到了什么。嗨@ScottKurz,我终于有时间实现整个代码了。在JBeret中(JBoss impl.of JSR352),作业参数似乎在作业(首次)启动时自动保留。因此,如果作业在没有参数的情况下重新启动,则将再次使用保留的作业参数。这就是为什么我认为反序列化的位置不重要的原因。但我可能错了。在WebSphere Batch中,作业重新启动角色的情况是否相同?
MyObject myObj = (MyObject) jobCtx.getTransientUserData();