Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

ScriptRunner Clone project on transition - problem with issues

Hi,

 

I trying prepare self service to creating JIRA projects. Now in JIRA working project clone, but just without issues - everythink looks good, but i last case i need copy Issues from source project. I trying a lot things with code like below :

package examples
import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.atlassian.jira.issue.Issue
//import com.onresolve.jira.groovy.user.FormField
import org.apache.log4j.Logger
import org.apache.log4j.Level

Logger.getLogger("com.onresolve").setLevel(Level.DEBUG)
def log = Logger.getLogger("com.onresolve.jira.groovy.MyCopyProjectScript")
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def destProjetKey = 'ASAP'
def srcProjectKey = 'SPP'
def destProjectName = 'ASAP'

log.debug("Source Project Name: " + srcProjectKey)

Thread executorThread = new Thread(new Runnable() {
void run() {
def copyProject = new CopyProject()
def inputs = [
(CopyProject.FIELD_SOURCE_PROJECT) : srcProjectKey,
(CopyProject.FIELD_TARGET_PROJECT) : destProjetKey,
(CopyProject.FIELD_TARGET_PROJECT_NAME) : destProjectName,
(CopyProject.FIELD_COPY_VERSIONS) : true,
(CopyProject.FIELD_COPY_COMPONENTS) : true,
(CopyProject.FIELD_COPY_ISSUES) : true,
//(CopyProject.FIELD_COPY_GREENHOPPER) : false,
(CopyProject.FIELD_COPY_DASH_AND_FILTERS) : false,
(CopyProject.FIELD_ORDER_BY) : "Rank",
]

def errorCollection = copyProject.doValidate(inputs, false)
if(errorCollection.hasAnyErrors()) {
log.warn("Couldn't create project: " + errorCollection)
}
else {
def util = ComponentAccessor.getUserUtil()
def adminsGroup = ComponentAccessor.getGroupManager().getGroup("jira-administrators")
assert adminsGroup // must have jira-administrators group defined
def admins = util.getAllUsersInGroups([adminsGroup])
assert admins // must have at least one admin

def executingAdmin = ComponentAccessor.getUserManager().getUserByName(admins.first().name)
log.debug("Executing Admin: " + executingAdmin.getName())

ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(executingAdmin)
copyProject.doScript(inputs)
}
}
})
executorThread.run()

and without result. Code working fine in "Run Script" from Add-ons level, but from transition leve Issues is not able to copy (with error NullPointerException. In atlassian-jira I receiving:


2019-01-21 11:36:23,529 ajp-nio-8009-exec-2 ERROR 696x12002x1 1kbyjsn /secure/WorkflowUIDispatcher.jspa [c.o.s.c.jira.utils.AbstractCloneIssue] Failed to create issue
com.atlassian.jira.exception.CreateException: java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Expected one match for [Expr::id::=::15123] but found 0: []

and:

2019-01-21 11:36:23,544 ajp-nio-8009-exec-2 ERROR  696x12002x1 1kbyjsn /secure/WorkflowUIDispatcher.jspa [c.o.s.jira.workflow.ScriptWorkflowFunction] Script function failed on issue: SS-105, actionId: 111, file: <inline script>
java.lang.NullPointerException

 

I tried:

- remove any validators

- every place in post function 

- use 2 type of post funcions: JMWE groovy script and scriptu runner script

- allow everything for my user in permission scheme

- change executingadmin

but still everything working fine from Add-ons level, but not working from transition level.

 

 JIRA 7.10.2

ScriptRunner 5.4.47

 

 

Anyone have any idea? I will be grateful for any advise.

2 answers

Hi Wojciech

On the last line, you are calling the run method on the "executorThread" class you instantiated which does not actually create a new thread. It will just call the run method for the current thread.

If the current thread has already been started or stopped then you will get a IllegalStateException, like the one you have posted. You need to call the start method to create a new thread where your defined run method will execute.

I had a similar issue before when a user needed to clone a template project as a post function based on the value of some fields in the issue that they were transitioning. I will link it here as it may help you get your script working.

https://bitbucket.org/snippets/mclark_AV/ae9ejR/post-function-script-clone-template

Hi Matthew,

Thanks for answer! You have right. I got answer from adaptavista support and was this same :).

Regards,
Wojciech Miecznikowski

Like Matthew Clark likes this

Hi @Matthew Clark 

In the linked script you wrote a comment that it does not copy existing issues. We have the current version (5.6.7.1-jira8) and the same errors in the log as described by @Wojciech Miecznikowski.

We can copy the project but without issues. Could you already find a solution for that?

Best regards
Andreas

This only impacts Jira 8

Our CopyProject class has a slight difference in the Jira 8 version of scriptrunner. It still works in places where we call it internally like the built-in scripts, however, this change had an unexpected impact on users who are using our class by manually calling it in their scripts within POST functions.

The problem occurs when you try to run the CopyProject methods inside a thread within a POST function.
Some of the more complex CopyProject methods such as Copying Issues must be run inside a Thread when used as a POST function so unfortunately you cannot just take it out of the Thread and use it in a Post Function.

I created a bug ticket for this here SRJIRA-3793

You can still use our CopyProject class within a Listener as you do not need to run the CopyProject methods inside a Thread within a Listener.

Thank you for your fast reply. Unfortunately I don't really understand the thread problem :-) 

We are using a listener to copy the project but with an own event which is called by a postfunction. Should it copy the issues there or not? Do you know clean a workaround to copy the issues from the template after the project was created?

The listener should be able to copy issues.

I would need to see any atlassian-jira.log errors and the script to tell you why it might not be doing this if it is failing to.

I have seen other users trying this with custom events and it also failed. This is usually because the custom event object did not contain the correct properties required by their script.

Try your tests with a standard Jira Issue event like the Issue Updated or issue Created events.

I am sure you know this but make sure you do this on a test box. Playing around with issue updated/issue created events should always be done in a test environment to avoid spamming your users or accidentally creating loops.

You are right, after further tests i found a different error in the log. I have copied exactly your script and created a new listener with it. The error is the same when I use a custom event as when using the issue updated event. Seems like the script cannot find the correct table in the database....it tries to insert an entry into "NULL":

 

2019-11-12 21:34:27,788 JIRA-INFORM-Thread-0 ERROR ag 1294x291x1 nmlp4q 172.16.48.4 /secure/QuickCreateIssue.jspa [c.a.j.p.inform.performance.MeasurementWorkerFactory] Exception occured
com.querydsl.core.QueryException: Caught SQLServerException for insert into "null"."AO_733371_EVENT" ("CREATED", "EVENT_TYPE", "USER_KEY", "ACTION", "ACTION_ID", "EVENT_BUNDLE_ID") values (?, ?, ?, ?, ?, ?)
at com.querydsl.sql.DefaultSQLExceptionTranslator.translate(DefaultSQLExceptionTranslator.java:50)
at com.querydsl.sql.Configuration.translate(Configuration.java:459)
at com.querydsl.sql.dml.SQLInsertClause.executeWithKeys(SQLInsertClause.java:408)
at com.querydsl.sql.dml.SQLInsertClause.executeWithKey(SQLInsertClause.java:201)
at com.querydsl.sql.dml.SQLInsertClause.executeWithKey(SQLInsertClause.java:182)
at com.atlassian.jira.plugins.inform.events.managers.EventManagerImpl.lambda$add$2(EventManagerImpl.java:83)
at com.atlassian.pocketknife.internal.querydsl.DatabaseAccessorImpl.lambda$execute$0(DatabaseAccessorImpl.java:69)
at com.atlassian.sal.core.rdbms.DefaultTransactionalExecutor.executeInternal(DefaultTransactionalExecutor.java:87)
at com.atlassian.sal.core.rdbms.DefaultTransactionalExecutor.lambda$execute$0(DefaultTransactionalExecutor.java:43)
at com.atlassian.jira.database.DatabaseAccessorImpl.runInManagedTransaction(DatabaseAccessorImpl.java:131)
... 3 filtered
at java.lang.reflect.Method.invoke(Method.java:498)
at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
at com.sun.proxy.$Proxy429.runInManagedTransaction(Unknown Source)
... 3 filtered
at java.lang.reflect.Method.invoke(Method.java:498)
at com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:131)
at com.sun.proxy.$Proxy429.runInManagedTransaction(Unknown Source)
at com.atlassian.sal.jira.rdbms.JiraHostConnectionAccessor.runInStartedOrExistingTransaction(JiraHostConnectionAccessor.java:130)
at com.atlassian.sal.jira.rdbms.JiraHostConnectionAccessor.execute(JiraHostConnectionAccessor.java:60)
at com.atlassian.sal.core.rdbms.DefaultTransactionalExecutor.execute(DefaultTransactionalExecutor.java:40)
at com.atlassian.pocketknife.internal.querydsl.DatabaseAccessorImpl.execute(DatabaseAccessorImpl.java:67)
at com.atlassian.pocketknife.internal.querydsl.DatabaseAccessorImpl.runInTransaction(DatabaseAccessorImpl.java:43)
at com.atlassian.jira.plugins.inform.events.managers.EventManagerImpl.add(EventManagerImpl.java:74)
at com.atlassian.jira.plugins.inform.events.listener.EventSaverImpl.lambda$save$0(EventSaverImpl.java:30)
at com.atlassian.jira.plugins.inform.performance.MeasurementWorkerFactory$1.measure(MeasurementWorkerFactory.java:39)
at com.atlassian.jira.plugins.inform.events.listener.EventSaverImpl.save(EventSaverImpl.java:26)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:419)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at com.atlassian.jira.plugins.inform.events.listener.JiraEventListenerImpl.lambda$handleIssueEventBundle$5(JiraEventListenerImpl.java:63)
at com.atlassian.jira.plugins.inform.performance.MeasurementWorkerFactory$1.lambda$measure$0(MeasurementWorkerFactory.java:60)
at com.atlassian.jira.plugins.inform.performance.MeasurementWorkerFactory$1.measure(MeasurementWorkerFactory.java:39)
at com.atlassian.jira.plugins.inform.performance.MeasurementWorkerFactory$1.measure(MeasurementWorkerFactory.java:60)
at com.atlassian.jira.plugins.inform.events.listener.JiraEventListenerImpl.handleIssueEventBundle(JiraEventListenerImpl.java:52)
at com.atlassian.jira.plugins.inform.events.listener.AsyncJiraEventListener.lambda$handleIssueEventBundle$0(AsyncJiraEventListener.java:27)
at com.atlassian.jira.plugins.inform.events.listener.EventThreadPool.lambda$wrapThreadLocalSafe$0(EventThreadPool.java:48)
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:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'null.AO_733371_EVENT'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:256)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1621)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:592)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:522)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7194)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:248)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:223)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:471)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98)
at com.atlassian.jira.ofbiz.sql.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:47)
at com.atlassian.jira.diagnostic.connection.DiagnosticPreparedStatement.lambda$executeUpdate$7(DiagnosticPreparedStatement.java:69)
at com.atlassian.diagnostics.internal.platform.monitor.db.DefaultDatabaseDiagnosticsCollector.recordExecutionTime(DefaultDatabaseDiagnosticsCollector.java:69)
at com.atlassian.jira.diagnostic.connection.DatabaseDiagnosticsCollectorDelegate.recordExecutionTime(DatabaseDiagnosticsCollectorDelegate.java:55)
at com.atlassian.jira.diagnostic.connection.DiagnosticPreparedStatement.executeUpdate(DiagnosticPreparedStatement.java:69)
at com.querydsl.sql.dml.SQLInsertClause.executeWithKeys(SQLInsertClause.java:368)
... 56 more

 

We have a similar issue if we enable the E-Mail batching feature:

https://community.atlassian.com/t5/Jira-Software-discussions/Jira-does-not-send-emails-when-batching-email-functionality-is/td-p/1226159

I am not sure if this is a Scriptrunner issue. It looks like your server is having trouble finding the DATABASE name. (sometimes named jiradb)

Caught SQLServerException for insert into "null"."AO_733371_EVENT" 

You get the same type of "null" error in your batch email functionality issue you linked

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'null.AO_0A5972_NOTIFICATION_SETTING'

I believe the "null" part should be the name of the database and it is strange that it cannot find it. I would need to research more but it might be a database permission problem. Can you access the database as the user that the Jira process runs as and check what databases you can see and if they contain the above table names?

With the help of Atlassian Support we were able to solve this issue. The problem was the missing database scheme in dbconfig.xml. The SQL exceptions do not appear any more.

Now I tried again to create a new project including issues.
If I try to use your script again including creating a new thread it still does not create any issue. This time there is no error in the log anymore. I tried to add some log messages into the script - from the line with the command "copyProject.doScript(inputs)" no further log messages are visible in the log file. Do you have an idea why this occurs?

Apologies for the delay it has been very busy lately.

The problem you describe above is what this bug I linked earlier is for SRJIRA-3793

I believe we need to alter the CopyProject class in order for users to be able to manually call it from a post-function script so the bug will need to be fixed before it can be used in a POST function to copy Projects.

You should be able to use our CopyProject class with a listener instead as long as you remove the parts that put it in a Thread.

Make sure your listener script does not listen for all projects as that could potentially cause a loop of project creation.

Hello matthew

I tried your suggested solution , i used a listener to copy project with issues instead of a Post Function . But it didn't work. The issues are not copied.

Is there another solution please and when you will fix this problem for JIRA 8 ?

Thank you in advance for your answer.

Best Regards

Issue type scheme is not being copied from source project. It takes default issue type scheme.

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Jira

Admins, notify your Jira instance of system-wide changes with the new admin announcement banner

Hi All! We’re excited to share the launch of an announcement banner that lets Jira site administrators communicate directly to their users across their  Jira Cloud instance.  ...

481 views 16 17
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you