9

JenkinsがJellyフォームから発信されたJSONデータを呼び出すことができるコンストラクターの作成に問題があります。mvn hpi:createテストのために、次の2つのカスタムファイルを使用して最小限のJenkinsプラグインを作成しました。

src / main / resources / foo / hyde / jenkins / plugins /OptionalBlockSampleBuilder / config.jelly

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:block>
    <table>
        <f:optionalBlock name="enableText" title="Enable optional text" checked="${instance.enableText}">
            <f:entry title="Optional text" field="text">
                <f:textbox />
            </f:entry>
        </f:optionalBlock>
    </table>
</f:block>

src / main / java / foo / hyde / jenkins / plugins /OptionalBlockSampleBuilder.java

package foo.hyde.jenkins.plugins;

public class OptionalBlockSampleBuilder extends hudson.tasks.Builder {

    public final String text;
    public final boolean enableText;

    @org.kohsuke.stapler.DataBoundConstructor
    public OptionalBlockSampleBuilder(String text, Boolean enableText) {
        this.text = text;
        this.enableText = (enableText != null) && enableText;
    }

    @Override
    public boolean perform(hudson.model.AbstractBuild build, hudson.Launcher launcher, hudson.model.BuildListener listener) {
        listener.getLogger().println("OptionalBlockSampleBuilder " + enableText + "/" + text);
        return true;
    }

    @hudson.Extension
    public static final class DescriptorImpl extends hudson.tasks.BuildStepDescriptor<hudson.tasks.Builder> {
        public boolean isApplicable(Class<? extends hudson.model.AbstractProject> aClass) {
            return true;
        }
        public String getDisplayName() {
            return "Optional Block Sample";
        }
    }
}

私はpom.xmlの親に対して<groupId>org.jenkins-ci.plugins</groupId><artifactId>plugin</artifactId><version>1.454</version>ビルドしており、すべてがビルドされます。Netbeans6.9.1はDebug Jenkinsを起動し、このビルドステップでジョブを作成できます。そのチェックボックスをチェックしないとすべてが機能し、OptionalBlockSampleBuilder false/nullジョブのコンソール出力が期待されます。

しかし、チェックボックスをオンにしてテキストを追加すると、ジョブ構成を保存/適用すると、コンストラクターを呼び出そうとしたときに、Jenkinsコードの深さからこの例外が発生します。

java.lang.RuntimeException:
  Failed to instantiate class
    foo.hyde.jenkins.plugins.OptionalBlockSampleBuilder 
  from {
    "enableText":{"text":"xx"},
    "kind":"foo.hyde.jenkins.plugins.OptionalBlockSampleBuilder",
    "stapler-class":"foo.hyde.jenkins.plugins.OptionalBlockSampleBuilder"
    }

簡単な修正が必要です。私はさまざまな変更を試し、他のプラグインがそれをどのように使用するかを確認し、最終的にこの最小限のテストプラグインを作成しました。オプションのブロックを機能させるためにそれを修正する方法は?

4

2 に答える 2

16

ヒントはJSONデータから得られます。

{
"enableText":{"text":"xx"},
"kind":"foo.hyde.jenkins.plugins.OptionalBlockSampleBuilder",
"stapler-class":"foo.hyde.jenkins.plugins.OptionalBlockSampleBuilder"
}

enableText子プロパティを含むここを見ることができますtext。これは、f:optionalBlockが実際にブロック内に含まれるすべてのフィールドのカプセル化を期待していることを意味します。ブロックがチェックされると、カプセル化フィールドクラスのインスタンスを受け取ります。チェックを外すと、そのフィールドはになりますnull。適切に使用するには、全体をカプセル化する単一のnull許容クラスインスタンスを取り込むoptionalBlock必要があります。例えば:@DataBoundConstructoroptionalBlock

private String text;

@DataBoundConstructor
public MyClass(EnableTextBlock enableText)
{
    if (enableText != null)
    {
        this.text = enableText.text;
    }
}

public static class EnableTextBlock
{
    private String text;

    @DataBoundConstructor
    public EnableTextBlock(String text)
    {
        this.text = text;
    }
}

enableTextこの場合のフィールドは、実際にEnableTextBlockは子プロパティを含むクラスのインスタンスであることに注意してくださいtext。これにより、フォームで送信されるJSONオブジェクトが満たされます。


代わりに、必要なのがそのフィールドの入力を有効にするチェックボックスを持つ単一のフィールドだけである場合は、代わりにf:optionalPropertyタグを使用することを検討することをお勧めします。これにより、その単一フィールドのカプセル化が処理されます。ただし、多くの場合、optionalBlock実際には複数のフィールドを構成するために必要です。その場合、上記の例のように、カプセル化クラスが通常正しい方法です。

カプセル化クラスは静的内部クラスである必要はありません。パッケージ内の別個のクラスである可能性がありますが、重要な部分はDataBoundConstructor、フォームから渡されるJSON構造に一致する引数を受け取る必要があるということです。

于 2012-10-26T17:17:39.057 に答える
11

inlineまたは、次のようにoptionalBlockにタグを追加できます。

<f:optionalBlock inline="true">

が存在する場合inline、折り畳み可能なセクションは送信時に個別のJSONオブジェクトにグループ化されません。

于 2014-07-31T22:04:03.947 に答える