我是Java的新手。我正在构建一个数组列表来保存我的Git提交中的部分文本。我在Jenkins的Groovy脚本中运行它。
def commits = sh script: """ git log ${previous_tag}..HEAD --oneline --decorate""", returnStdout: true
def array = commits.split("\\n");
ArrayList<String> mystats = new ArrayList<>(array.length);
for(int i =0; i < array.length; i++) {
Pattern pattern = Pattern.compile("^\\w{7}\\s(MYSTATS-|mystats-)");
Matcher matcher = pattern.matcher(array[i]);
if(matcher.find()) {
mystats.add(array[i])
}
}
我想要做的是创建另一个数组来保存唯一值(所以不要复制任何东西)并且建议HashSet是最好的方法,因为它会拒绝重复的值
// Put all unique mystats matches into a set
Set<String> mystats_set = new HashSet<String>(mystats.size());
for(int i =0; i < mystats.size(); i++) {
Pattern pattern = Pattern.compile("(MYSTATS-|mystats-)\\w+");
Matcher matcher = pattern.matcher(mystats[i]);
if(matcher.find()) {
String id = matcher.group().toUpperCase().toString();
def jira_json = sh script: '''curl --cert ../certs/dev_cert.p12:password https://jira.dev.organisation.co.uk:port_number/rest/api/2/issue/${id}''', returnStdout: true
mystats_set.add("[" + id + "](https://jira.dev.organisation.co.uk/browse/" + id + ")");
}
}
当这个运行时,我得到了
java.io.NotSerializableException: java.util.regex.Matcher
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.HashMap.internalWriteEntries(HashMap.java:1785)
at java.util.HashMap.writeObject(HashMap.java:1362)
at sun.reflect.GeneratedMethodAccessor202.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.TreeMap.writeObject(TreeMap.java:2438)
at sun.reflect.GeneratedMethodAccessor204.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:132)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:429)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:408)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:356)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:78)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:236)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:224)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
引起:发生的异常: 在当地的本地人 在现场父母 在现场来电者 在现场e 在实地计划 在字段线程中 在对象org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@4f76de19
所以经过一些阅读后,似乎Set
不可序列化?如果是这种情况,我怎么才能拥有一个仅包含唯一值的ArrayList并拒绝重复的条目?
答案 0 :(得分:2)
好吧,在添加完整的堆栈跟踪后,现在看来Matcher
是问题,因为它不可序列化
您检查了this吗?
我决定:
你会注意到一个问题:
java.io.NotSerializableException:java.util.regex.Matcher 发生这种情况 因为匹配器局部变量属于类型(匹配器)而不是 被Java认为是可序列化的。由于管道必须在詹金斯生存 重新启动,定期保存正在运行的程序的状态 磁盘,以便以后可以恢复(保存发生在每一步或之后) 中间的步骤,如sh)。 ...
查看链接以获取更多信息
帖子建议使用注释@NonCPS
作为声明Matcher
的方法。因为我再次询问:
这种方法将被Pipeline引擎视为“本机”,并且 它的局部变量从未保存
前,
@NonCPS
public void doSomeWork(){
ArrayList<String> mystats = new ArrayList<>(array.length);
for(int i =0; i < array.length; i++) {
Pattern pattern = Pattern.compile("^\\w{7}\\s(MYSTATS-|mystats-)");
Matcher matcher = pattern.matcher(array[i]);
if(matcher.find()) {
mystats.add(array[i])
}
}
}
和使用Matcher
基于您发布的答案,使用瞬态的其他解决方案
您必须声明方法中的Matcher
才能使用transient
我不确定您的代码的上下文,或者您是否可以声明Matcher
并在以后使用它,例如:
transient Matcher matcher = null;
def commits = sh script: """ git log ${previous_tag}..HEAD --oneline --decorate""", returnStdout: true
def array = commits.split("\\n");
ArrayList<String> mystats = new ArrayList<>(array.length);
for(int i =0; i < array.length; i++) {
Pattern pattern = Pattern.compile("^\\w{7}\\s(MYSTATS-|mystats-)");
matcher = pattern.matcher(array[i]);
if(matcher.find()) {
mystats.add(array[i])
}
}
和代码的第二部分相同,除非它们在同一个类(范围)中,否则无需重新声明Matcher