Hi! If you have a dependency on jira-rest-plugin
you have to migrate your plugin to RESTv2 for the imports to resolve correctly.
You can also consider making OSGi imports of your plugin mandatory instead of optional. It would make the system display clear error right at the bundle resolution stage (I suppose javax.ws.rs.*
versions mismatch) instead of cryptic runtime ClassNotFounds
.
Hi! the rfc you linked refers to the platform level changes.
However, In products might override the visibility of certain libraries - hence the mismatches between platformās RFC and Jiraās changelog. Do you have a question or a suggestion about any specific lib?
Will it be continued to be supported in AMPS?
Or should we expect that half of local DC development routines might get broken in future Jira releases?
We will continue to support H2 in AMPS for now, but weāre for sure not going to break any local DC development environment. Most probably, we will replace H2 with Docker + different database engine (like PostgreSQL for example) in the future.
Please do not do this. Do not add this to AMPS. There is already the DC testing terraform solution available and it isnāt difficult to set up Docker-based development ourselves. This is not the DX improvement you are looking for.
To be honest @mkemp I personally donāt care about hot reload. Iāve never tried implementing it. Iām actually pretty happy with our current Docker-based DC development flow.
On a side note, not entirely related to this topic: is there any plans for semi-/official docker images for arm64, at least for dev purposes?
Disagreed. Weād appreciate it being in Amps. We really just run raw atlas-run commands without any deployment solution, so pushing us into Terraform today would be a huge hinderance to our roadmap.
AMPS is a maven-based solution (Atlassian Maven Plugin Suite). Adding docker execution from within Maven execution is going to be messy. If Atlassian wants to provide a docker-based solution to app development, it should be outside of the Maven process.
To be honest, I think the whole CLI should be rewritten and not be Maven-based. That way it could also start supporting other build tools (Ant, Gradle, etc). It is also taking on responsibilities it should not care about (like resource minification).
Oh well, maybe I should just write my own CLI.
I hear what youāre saying and I understand what you mean now, thanks. Appreciate you.
I agree, AMPS should not start executing docker commands. Whether it should or shouldnāt support other tools outside of Maven I leave to those that use other tools.
From the start I never used the AMPS CLI, I simply use the AMPS Maven plugin in my projects and use ānormalā Maven commands to build my apps.
Having said this, if H2 is being removed, then AMPS should support, or at least make it easy, to āimportā a database from another source, like docker. One thing that comes to mind is that AMPS should be able to populate an external DB just like it does now with H2. This would make it easy for dev to adopt it and not have to worry about going through the initial install process when starting an instance using AMPS.
Hi There,
We are trying our plugin with jira 10 EAP, plugin not getting enabled and giving following error for SprintService class , Is there any change in that ?
failed; nested exception is java.lang.NoClassDefFoundError: com/atlassian/greenhopper/service/sprint/SprintService
Please guide me
If you havenāt upgraded your plugin to rest v2, start with that.
Iāve encountered a similar issue, it was caused by constraint violation exception in bundle class loader due to conflict between imports from rest v1 and imports from JSW.
Setting log level for org.apache.felix.framework.BundleWiringImpl
to DEBUG might help to troubleshoot.
Thanks for the reply, I will try that way.
Is this change included in EAP02, or should we wait for next one?
Iām seeing this warning in log and failure to resolve the jackson package:
Package com.fasterxml.jackson.databind is internal and is not available for export to plugin xxx.xxx
Thanks @lexek-92 for raising this. It looks like something gone wrong on our side. Weāll have it investigated and fixed by next EAP.
Hello team; we wanted to inform you about features and changes we plan to include in upcoming Jira Software 10.0 / Jira Service Management 6.0 EAPs.
Deprecated code removals
Status: IN PROGRESS
The design of this feature hasnāt been finalised; please check back for more details.
We are planning to:
- Remove deprecated Java methods and classes listed below:
Change | Instructions |
---|---|
com.atlassian.jira.auditing.AssociatedItem | Use com.atlassian.audit.entity.AuditResource instead |
com.atlassian.jira.auditing.AuditingCategory | Use com.atlassian.jira.auditing.AuditCategory instead |
com.atlassian.jira.auditing.AuditingFilter | Use com.atlassian.audit.api.AuditQuery instead |
com.atlassian.jira.auditing.AuditingManager#countRecords | Use com.atlassian.audit.api.AuditSearchService#count instead |
com.atlassian.jira.auditing.AuditingManager#getRecords | Use com.atlassian.audit.api.AuditSearchService#findBy or com.atlassian.audit.api.AuditSearchService#stream instead |
com.atlassian.jira.auditing.AuditingManager#store | Use com.atlassian.audit.api.AuditService#audit instead |
com.atlassian.jira.auditing.AuditingService#getRecords | Use com.atlassian.audit.api.AuditSearchService#findBy or com.atlassian.audit.api.AuditSearchService#stream instead |
com.atlassian.jira.auditing.AuditingService#getTotalNumberOfRecords | Use com.atlassian.audit.api.AuditSearchService#count instead |
com.atlassian.jira.auditing.AuditingService#storeRecord | Use com.atlassian.audit.api.AuditService#audit instead |
com.atlassian.jira.auditing.AuditRecord | Use com.atlassian.audit.entity.AuditEntity instead |
com.atlassian.jira.auditing.ChangedValue | Use com.atlassian.audit.entity.ChangedValue instead |
com.atlassian.jira.auditing.RecordRequest | Use com.atlassian.audit.entity.AuditEvent instead |
com.atlassian.jira.auditing.Records.getRecords() | Use #getResults instead |
com.atlassian.jira.bc.customfield.CustomFieldDefinition.CustomFieldDefinition() | Use a Builder to create the definition |
com.atlassian.jira.bc.issue.comment.CommentService.CommentParameters.getGroupLevel() | Use #getVisibility() instead |
com.atlassian.jira.bc.issue.comment.CommentService.CommentParameters.getRoleLevelId() | Use #getVisibility() instead |
com.atlassian.jira.bc.issue.comment.CommentService.isGroupVisiblityEnabled() | Use #isGroupVisibilityEnabled() instead |
com.atlassian.jira.bc.issue.comment.CommentService.isProjectRoleVisiblityEnabled() | Use #isProjectRoleVisibilityEnabled() instead |
com.atlassian.jira.bc.issue.comment.CommentService.isValidCommentData(com.atlassian.jira.user.ApplicationUser, com.atlassian.jira.issue.Issue, java.lang.String, java.lang.String, com.atlassian.jira.util.ErrorCollection) | Use #isValidCommentVisibility(ApplicationUser,Issue,com.atlassian.jira.bc.issue.visibility.Visibility,ErrorCollection) instead |
com.atlassian.jira.bc.issue.util.VisibilityValidator.isGroupVisiblityEnabled() | Use #isGroupVisibilityEnabled() instead |
com.atlassian.jira.bc.issue.util.VisibilityValidator.isProjectRoleVisiblityEnabled() | Use #isProjectRoleVisibilityEnabled() instead |
com.atlassian.jira.bc.issue.worklog.WorklogInputParametersImpl.getGroupLevel() | Use #getVisibility() instead |
com.atlassian.jira.bc.issue.worklog.WorklogInputParametersImpl.getRoleLevelId() | Use #getVisibility() instead |
com.atlassian.jira.bc.license.JiraLicenseService.ValidationResult.getLicenseVersion() | Use #getLicenseDetails().getLicenseVersion() instead |
com.atlassian.jira.bc.license.JiraLicenseService.ValidationResult.getTotalUserCount() | Use com.atlassian.jira.application.ApplicationAuthorizationService#getUserCount(ApplicationKey) or com.atlassian.jira.user.util.UserManager#getTotalUserCount() instead |
com.atlassian.jira.bc.portal.PortalPageService.updatePortalPageUnconditionally(com.atlassian.jira.bc.JiraServiceContext, com.atlassian.jira.user.ApplicationUser, com.atlassian.jira.portal.PortalPage) | Use #updatePortalPageOwner, #updatePortalPage, or PortalPageManager#update instead |
com.atlassian.jira.bc.project.version.VersionService.validateReleaseDate(com.atlassian.jira.user.ApplicationUser, com.atlassian.jira.project.version.Version, java.lang.String) | Use #validateUpdate(com.atlassian.jira.user.ApplicationUser,com.atlassian.jira.bc.project.version.VersionService.VersionBuilder) instead |
com.atlassian.jira.bc.project.version.VersionService.validateVersionDetails(com.atlassian.jira.user.ApplicationUser, com.atlassian.jira.project.version.Version, java.lang.String, java.lang.String) | Use #validateUpdate(com.atlassian.jira.user.ApplicationUser,com.atlassian.jira.bc.project.version.VersionService.VersionBuilder) |
com.atlassian.jira.bc.user.UserService.validateRemoveUserFromApplication(com.atlassian.jira.user.ApplicationUser, com.atlassian.application.api.ApplicationKey) | Use UserService#validateRemoveUserFromApplication(com.atlassian.jira.user.ApplicationUser,com.atlassian.jira.user.ApplicationUser,com.atlassian.application.api.ApplicationKey) instead |
com.atlassian.jira.bc.whitelist.WhitelistService.getRules(com.atlassian.jira.bc.JiraServiceContext) | Use com.atlassian.plugins.whitelist.WhitelistService#getAll() instead |
com.atlassian.jira.bc.whitelist.WhitelistService.validateUpdateRules(com.atlassian.jira.bc.JiraServiceContext, java.util.List<java.lang.String>, boolean) | Use com.atlassian.plugins.whitelist.WhitelistService#add(com.atlassian.plugins.whitelist.WhitelistRule), com.atlassian.plugins.whitelist.WhitelistService#remove(int), com.atlassian.plugins.whitelist.WhitelistService#disableWhitelist() and com.atlassian.plugins.whitelist.WhitelistService#enableWhitelist() instead |
com.atlassian.jira.bulkedit.BulkOperationManager.getBulkOperations() | Use #getProgressAwareBulkOperations() instead |
com.atlassian.jira.bulkedit.operation.BulkMoveOperation.moveIssuesAndIndex(com.atlassian.jira.web.bean.BulkEditBean, com.atlassian.jira.user.ApplicationUser) | Use #moveIssuesAndIndex(com.atlassian.jira.web.bean.BulkEditBean,com.atlassian.jira.user.ApplicationUser) instead |
com.atlassian.jira.config.ConstantsManager.storeIssueTypes(java.util.List<org.ofbiz.core.entity.GenericValue>) | Use #updateIssueType(String,String,Long,String,String,Long) or #recalculateIssueTypeSequencesAndStore(java.util.List) instead |
com.atlassian.jira.config.properties.LookAndFeelBean.getVersion() | Use #getSettingsHash() instead |
com.atlassian.jira.config.properties.LookAndFeelBean.updateVersion(long) | Use #updateSettingsHash() instead |
com.atlassian.jira.config.SubTaskManager.insertSubTaskIssueType(java.lang.String, java.lang.Long, java.lang.String, java.lang.String) | Use #insertSubTaskIssueType(String,Long,String,Long) instead |
com.atlassian.jira.config.SubTaskManager.updateSubTaskIssueType(java.lang.String, java.lang.String, java.lang.Long, java.lang.String, java.lang.String) | Use #updateSubTaskIssueType(String,String,Long,String,Long) instead |
com.atlassian.jira.event.issue.IssueWatcherAddedEvent.getUser() | Use #getApplicationUser() instead |
com.atlassian.jira.event.issue.IssueWatcherDeletedEvent.getUser() | Use #getApplicationUser() instead |
com.atlassian.jira.event.mail.EmailQueueFlashedEvent | Use EmailQueueFlushedEvent instead |
com.atlassian.jira.help.HelpUrlsParser.defaultUrl(java.lang.String, java.lang.String) | Use HelpUrlsParserBuilderFactory instead |
com.atlassian.jira.help.HelpUrlsParser.onDemand(boolean) | Use HelpUrlsParserBuilderFactory instead |
com.atlassian.jira.imports.project.mapper.ProjectImportIdMapper.getValuesFromImport() | Use getRegisteredOldIds() instead |
com.atlassian.jira.imports.project.mapper.ProjectRoleActorMapper.getAllProjectRoleActors() | Use the properly typed method #getProjectRoleActors() instead |
com.atlassian.jira.issue.comments.CommentManager.getProjectRole(java.lang.Long) | Use com.atlassian.jira.security.roles.ProjectRoleManager#getProjectRole(Long) instead |
com.atlassian.jira.issue.customfields.CustomFieldType.getNonnullCustomFieldProvider() | Use #getNonNullCustomFieldProvider() instead |
com.atlassian.jira.issue.customfields.vdi.NonNullCustomFieldProvider.getCustomFieldInfo(com.atlassian.jira.issue.Issue) | Use getCustomFieldInfo(List issues) instead |
com.atlassian.jira.issue.fields.layout.field.FieldLayoutStorageException | No replacement |
com.atlassian.jira.issue.fields.rest.json.CommentBeanFactory.createRenderedBean(com.atlassian.jira.issue.comments.Comment) | Use #createRenderedBean(com.atlassian.jira.issue.comments.Comment) instead |
com.atlassian.jira.issue.index.ReindexAllCompletedEvent.shouldUpdateReplicatedIndex() | Use #shouldNotifyCluster() instead |
com.atlassian.jira.issue.index.ReindexAllStartedEvent.shouldUpdateReplicatedIndex() | Use #shouldNotifyCluster() instead |
com.atlassian.jira.issue.search.managers.IssueSearcherManager.getSearcherGroups(com.atlassian.jira.issue.search.SearchContext) | Use #getSearcherGroups() instead |
com.atlassian.jira.issue.search.managers.SearchHandlerManager.getSearcherGroups(com.atlassian.jira.issue.search.SearchContext) | Use #getSearcherGroups() |
com.atlassian.jira.issue.search.managers.SearchHandlerManager.getSearchersByClauseName(com.atlassian.jira.user.ApplicationUser, java.lang.String, com.atlassian.jira.issue.search.SearchContext) | Use #getSearchersByClauseName(com.atlassian.crowd.embedded.api.User,String) instead |
com.atlassian.jira.issue.search.searchers.util.IndexedInputHelper.getAllIndexValuesForMatchingClauses(com.atlassian.jira.user.ApplicationUser, com.atlassian.jira.issue.search.ClauseNames, com.atlassian.query.Query, com.atlassian.jira.issue.search.SearchContext) | Use #getAllIndexValuesForMatchingClauses(com.atlassian.jira.user.ApplicationUser,com.atlassian.jira.issue.search.ClauseNames,com.atlassian.query.Query) instead |
com.atlassian.jira.issue.search.searchers.util.IndexedInputHelper.getAllNavigatorValuesForMatchingClauses(com.atlassian.jira.user.ApplicationUser, com.atlassian.jira.issue.search.ClauseNames, com.atlassian.query.Query, com.atlassian.jira.issue.search.SearchContext) | Use #getAllNavigatorValuesForMatchingClauses(ApplicationUser,com.atlassian.jira.issue.search.ClauseNames,com.atlassian.query.Query) instead |
com.atlassian.jira.issue.util.IssueUpdateBean.getUser() | Use #getApplicationUser() instead |
com.atlassian.jira.jql.query.AbstractLocalDateOperatorQueryFactory | Use com.atlassian.jira.jql.util.JqlLocalDateSupport#getLocalDatesFromQueryLiterals(java.util.List) instead |
com.atlassian.jira.jql.util.JqlIssueSupport.getIssues(java.lang.String) | Use #getIssue(String) instead |
com.atlassian.jira.jql.util.JqlIssueSupport.getIssues(java.lang.String, com.atlassian.jira.user.ApplicationUser) | Use #getIssue(String,com.atlassian.jira.user.ApplicationUser) instead |
com.atlassian.jira.license.LicenseDetails.getLicenseStatusMessage(com.atlassian.jira.user.ApplicationUser, java.lang.String, com.atlassian.jira.user.util.UserManager) | Use #getLicenseStatusMessage(com.atlassian.jira.util.I18nHelper,UserManager) instead |
com.atlassian.jira.license.LicenseDetails.getLicenseStatusMessage(com.atlassian.jira.util.I18nHelper, com.atlassian.jira.web.util.OutlookDate, java.lang.String, com.atlassian.jira.user.util.UserManager) | Use #getLicenseStatusMessage(com.atlassian.jira.util.I18nHelper,UserManager) instead |
com.atlassian.jira.license.LicenseDetails.isLicenseAlmostExpired() | Use LicenseDetails#getMaintenanceExpiryDate instead |
com.atlassian.jira.mention.MentionService.sendCommentMentions(com.atlassian.jira.user.ApplicationUser, java.util.Set<com.atlassian.jira.notification.NotificationRecipient>, com.atlassian.jira.issue.comments.Comment, com.atlassian.jira.issue.comments.Comment) | Use #sendCommentMentions(Set,ApplicationUser,Comment,Comment) instead |
com.atlassian.jira.mention.MentionService.sendIssueCreateMentions(com.atlassian.jira.user.ApplicationUser, java.util.Set<com.atlassian.jira.notification.NotificationRecipient>, com.atlassian.jira.issue.Issue) | Use #sendIssueCreateMentions(Set,ApplicationUser,Issue) instead |
com.atlassian.jira.mention.MentionService.sendIssueEditMentions(com.atlassian.jira.user.ApplicationUser, java.util.Set<com.atlassian.jira.notification.NotificationRecipient>, com.atlassian.jira.issue.Issue, com.atlassian.jira.issue.comments.Comment) | Use #sendIssueEditMentions(Set,ApplicationUser,Issue,Comment) instead |
com.atlassian.jira.permission.PermissionSchemeManager.getEntitiesByType(org.ofbiz.core.entity.GenericValue, com.atlassian.jira.security.plugin.ProjectPermissionKey, java.lang.String) | Use #getPermissionSchemeEntries(long,com.atlassian.jira.security.plugin.ProjectPermissionKey,String) instead |
com.atlassian.jira.permission.PermissionSchemeManager.getGroups(java.lang.Long, com.atlassian.jira.project.Project) | Use #getGroups(ProjectPermissionKey,Project) instead |
com.atlassian.jira.plugin.keyboardshortcut.KeyboardShortcutManager.getActiveShortcuts() | Use #listActiveShortcutsUniquePerContext instead |
com.atlassian.jira.plugin.webfragment.conditions.AbstractJiraPermissionCondition | Use AbstractPermissionCondition instead. |
com.atlassian.jira.plugin.webfragment.conditions.AbstractPermissionCondition | Use AbstractProjectPermissionCondition instead. |
com.atlassian.jira.project.type.ProjectTypesEnabledCondition | No replacement |
com.atlassian.jira.scheme.SchemeManager.createScheme(java.lang.String, java.lang.String) | Use #createSchemeObject(String,String) instead. |
com.atlassian.jira.scheme.SchemeManager.getGroups(java.lang.Long, org.ofbiz.core.entity.GenericValue) | Use #getGroups(Long,com.atlassian.jira.project.Project) instead |
com.atlassian.jira.security.GlobalPermissionEntry.getGlobalPermissionType() | Use #getPermissionKey() instead |
com.atlassian.jira.security.JiraAuthenticationContext.getI18nBean() | Use #getI18nHelper() instead |
com.atlassian.jira.security.JiraAuthenticationContext.getText(java.lang.String) | Use getText() method on #getI18nHelper() instead |
com.atlassian.jira.sharing.ShareManager.hasPermission(com.atlassian.jira.user.ApplicationUser, com.atlassian.jira.sharing.SharedEntity) | Use #isSharedWith(com.atlassian.crowd.embedded.api.User,SharedEntity) instead |
com.atlassian.jira.user.preferences.JiraUserPreferences.JiraUserPreferences() | You should not construct user preferences directly Request them through the UserPreferencesManager instead |
com.atlassian.jira.util.collect.MapBuilder.toFastMap() | Use ImmutableMap directly instead |
com.atlassian.jira.util.collect.MapBuilder.toImmutableMap() | Use #toMap() instead, or consider using ImmutableMap if the map does not need to accept nulls |
com.atlassian.jira.util.index.Contexts.nullContext() | Use #com.atlassian.jira.task.context.Contexts#nullContext() instead |
com.atlassian.jira.util.JiraDurationUtils.onClearCache(com.atlassian.jira.event.ClearCacheEvent) | Use #DurationFormatChanged instead |
com.atlassian.jira.util.JiraDurationUtils.start() | No replacement |
com.atlassian.jira.web.action.issue.IssueCreationHelperBean.getProvidedFieldNames(com.atlassian.jira.user.ApplicationUser, com.atlassian.jira.issue.Issue) | Use #getProvidedFieldNames(com.atlassian.jira.issue.Issue) instead |
com.atlassian.jira.web.bean.MultiBulkMoveBean.setTargetProject(org.ofbiz.core.entity.GenericValue) | Use #setTargetProject(com.atlassian.jira.project.Project) instead |
com.atlassian.jira.web.util.HelpUtil.HelpPath.getSimpleUrl() | Use #getUrl() instead |
com.atlassian.jira.web.util.OutlookDate.format() | Use #com.atlassian.jira.datetime.DateTimeFormatter#format(java.util.Date) instead |
com.atlassian.jira.web.util.OutlookDate.getCompleteDateFormat() | Use #com.atlassian.jira.datetime.DateTimeFormatter#getFormatHint() instead |
com.atlassian.jira.web.util.OutlookDate.getDatePickerFormat() | Use #com.atlassian.jira.datetime.DateTimeFormatter#getFormatHint() instead |
com.atlassian.jira.web.util.OutlookDate.getDateTimePickerFormat() | Use #com.atlassian.jira.datetime.DateTimeFormatter#getFormatHint() instead |
com.atlassian.jira.web.util.OutlookDate.getNow() | Use java.util.Date#Date() instead |
- Remove deprecated REST endpoints listed below:
Change | Instructions |
---|---|
Public endpoint GET /rest/api/2/group provided by com.atlassian.jira.rest.v2.issue.GroupResource#getGroup removed | Use GET /rest/api/2/group/member provided by com.atlassian.jira.rest.v2.issue.GroupResource#getUsersFromGroup |
Public endpoint DELETE /rest/api/2/version/{id} provided by com.atlassian.jira.rest.v2.issue.VersionResource#delete(java.lang.String, java.lang.String, java.lang.String) removed | Use POST /rest/api/2/version/{id}/removeAndSwap provided by com.atlassian.jira.rest.v2.issue.VersionResource#delete(String, DeleteAndReplaceVersionBean) |
Public endpoint GET /rest/api/2/auditing/record provided by com.atlassian.jira.rest.v2.admin.auditing.AuditingResource#getRecords removed | |
Public endpoint POST /rest/api/2/auditing/record provided by com.atlassian.jira.rest.v2.admin.auditing.AuditingResource#addRecord removed |
- Clean up a set of feature flags:
* jira.quick.search
* com.atlassian.jira.custom.csv.escaper
* atlassian.cdn.static.assets
* com.atlassian.jira.agile.darkfeature.burnupchart
* jira.users.and.roles.page.in.react
* optimistic.transitions
* com.atlassian.jira.advanced.audit.log
* velocity.chart.ui
See also API policy for Java APIs
No actions are required for this change.
Endpoint default security annotations
Status: IN PROGRESS
The design of this feature hasnāt been finalised; please check back for more details.
Our latest update will introduce changes for improved endpoint security where you can better control endpoint access with new annotations. Critical annotations to review are AdminOnly, AnonymousSiteAccess, LicensedOnly, SystemAdminOnly, UnlicensedSiteAccess, and UnrestrictedAccess. Theyāve been revised to ensure only the intended users access your application endpoints. Starting from Jira Software 10.0 / Jira Service Management 6.0, only licensed users can access resources without specified annotations of access criteria.
Discover the full details of this change on https://developer.atlassian.com/platform/marketplace/dc-apps-platform-7-preparing-for-secure-endpoints/
Allowlist your Velocity template class and method invocations
Status: IN PROGRESS
The design of this feature hasnāt been finalised; please check back for more details.
Like Confluence 9.0, starting from Jira Software 10.0 / Jira Service Management 6.0, we plan to migrate the method invocations in Velocity templates to an allowlist approach. All method invocations within a Velocity template will be explicitly allowed using a newly introduced annotation or app module descriptor.
Below are the allowed classes and methods:
introspector.allowlist.classes = java.io.Serializable,\
java.io.ObjectInputValidation,\
java.lang.reflect.Proxy,\
net.sf.hibernate.proxy.HibernateProxy,\
org.springframework.cglib.proxy.Factory
introspector.allowlist.methods = getEditVM,\
removeHtmlTags,\
htmlEncode,\
escapeHtml,\
getLabelSearchPath,\
encodeHtml,\
encodeForHtml
Additionally, all method invocations will be subject to a ādepthā limit, preventing context items from being traversed/chained indefinitely.
$contextItem.firstInvocation.secondInvocation.thirdInvocation
Allowlist your Velocity files on the filesystem
Status: IN PROGRESS
The design of this feature has yet to be finalized; please check back for further details.
We are making steps towards verifiably secure installation directories for all Data Centre products. This change not only increases the difficulty for an attacker to exploit filesystem access, but also allows customers to verify the state of the product installation.
From Bamboo 10.0, Bitbucket 9.0, Confluence 9.0, Crowd 6.0, Jira Software 10.0, and Jira Service Management 6.0, all Velocity files stored on the filesystem (e.g., shared, local home, or any other) will need to be explicitly allowlisted. Files stored inside of .jar
files and bundled within plugins will not be affected.
In Confluence, Jira Software, and Jira Service Management, itās possible to update the Velocity engine configuration to add files to the allowlist. This must be repeated for each new engine instance. This property is cached when the engine starts, enhancing performance and making it more difficult for attackers to disable.
velocity.addProperty(Velocity.RESOURCE_FILE_ALLOWLIST, "relative/file/path.vm")
Allowlist your Velocity filetypes for files on the filesystem
Status: IN PROGRESS
The design of this feature has yet to be finalized; please check back for further details.
We are making steps towards verifiably secure installation directories for all Data Centre products. This change not only increases the difficulty for an attacker to exploit filesystem access, but also allows customers to verify the state of the product installation.
From Bamboo 10.0, Bitbucket 9.0, Confluence 9.0, Crowd 6.0, and Jira Software 10.0, and Jira Service Management 6.0 onwards, all Velocity files stored on the filesystem (e.g., shared, local home, or any other) must be of a specific filetype. Files stored inside of .jar
files and bundled within plugins will not be affected.
In Confluence, Jira Software, and Jira Service Management, itās possible to update the Velocity engine configuration for the specific ResourceLoader
to add the filetypes to the allowlist. This must be repeated for each new engine instance. This property is cached when the engine starts, enhancing performance and making it more difficult for attackers to disable.
velocity.addProperty(Velocity.CLASSPATH_RESOURCE_FILETYPE_ALLOWLIST, ".vm,.vtl")
velocity.addProperty(Velocity.FILE_RESOURCE_FILETYPE_ALLOWLIST, ".vm,.vtl")
Disabling runtime JSP compilation
Status: IN PROGRESS
The design of this feature has yet to be finalized; please check back for further details.
Starting with Jira Software 10.0, and Jira Service Management 6.0 JSP runtime compilation is disabled. JSP files added to the Tomcat directory that are not shipped with the product will not be served. Furthermore, modifications to the JSP files will not be reflected. Please use Soy or Velocity templates instead.
Looking forward to hearing your feedback. Cheers.
The Jira team
When starting the Jira 10.0.0 EAP02 docker image I get this error and startup fails
- Image:
10.0.0-EAP02-ubuntu-jdk11
:
2024-04-14 19:19:45,749+0000 JIRA-Bootstrap ERROR [c.a.jira.upgrade.PluginSystemLauncher] A fatal error occured during initialisation. JIRA has been locked.
com.atlassian.jira.InfrastructureException: Error occurred while starting component 'com.atlassian.jira.instrumentation.Instrumentation'.
at com.atlassian.jira.component.pico.ComponentManager.startStartableComponents(ComponentManager.java:348)
at com.atlassian.jira.component.pico.ComponentManager.earlyStartPluginSystem(ComponentManager.java:259)
at com.atlassian.jira.upgrade.PluginSystemLauncher.start(PluginSystemLauncher.java:48)
at com.atlassian.jira.startup.DefaultJiraLauncher.lambda$postDbLaunch$2(DefaultJiraLauncher.java:151)
at com.atlassian.jira.config.database.DatabaseConfigurationManagerImpl.doNowOrEnqueue(DatabaseConfigurationManagerImpl.java:305)
at com.atlassian.jira.config.database.DatabaseConfigurationManagerImpl.doNowOrWhenDatabaseActivated(DatabaseConfigurationManagerImpl.java:202)
at com.atlassian.jira.startup.DefaultJiraLauncher.postDbLaunch(DefaultJiraLauncher.java:142)
at com.atlassian.jira.startup.DefaultJiraLauncher.lambda$start$0(DefaultJiraLauncher.java:108)
at com.atlassian.jira.util.devspeed.JiraDevSpeedTimer.run(JiraDevSpeedTimer.java:31)
at com.atlassian.jira.startup.DefaultJiraLauncher.start(DefaultJiraLauncher.java:106)
at com.atlassian.jira.startup.LauncherContextListener.initSlowStuff(LauncherContextListener.java:154)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.atlassian.cache.CacheException: com.atlassian.extras.common.LicenseException: java.lang.RuntimeException: Signature verification failed
at com.atlassian.cache.memory.DelegatingCachedReference.get(DelegatingCachedReference.java:92)
at com.atlassian.cache.impl.metrics.InstrumentedCachedReference.get(InstrumentedCachedReference.java:58)
at com.atlassian.jira.cache.stats.CachedReferenceWithStats.get(CachedReferenceWithStats.java:24)
at com.atlassian.jira.license.JiraLicenseManagerImpl.getLicenses(JiraLicenseManagerImpl.java:100)
at com.atlassian.jira.license.JiraLicenseManagerImpl.getLicenses(JiraLicenseManagerImpl.java:51)
at com.atlassian.jira.instrumentation.external.InternalStatisticsExternalGauges$1.<init>(InternalStatisticsExternalGauges.java:92)
at com.atlassian.jira.instrumentation.external.InternalStatisticsExternalGauges.registerLicenceInstruments(InternalStatisticsExternalGauges.java:91)
at com.atlassian.jira.instrumentation.external.InternalStatisticsExternalGauges.<init>(InternalStatisticsExternalGauges.java:84)
at com.atlassian.jira.instrumentation.external.ExternalGauges.installInstruments(ExternalGauges.java:26)
at com.atlassian.jira.instrumentation.Instrumentation.start(Instrumentation.java:151)
at com.atlassian.jira.component.pico.ComponentManager.startStartableComponents(ComponentManager.java:344)
... 11 more
Caused by: com.atlassian.extras.common.LicenseException: java.lang.RuntimeException: Signature verification failed
at com.atlassian.extras.decoder.v2.Version2LicenseDecoder.checkAndGetLicenseText(Version2LicenseDecoder.java:217)
at com.atlassian.extras.decoder.v2.Version2LicenseDecoder.doDecode(Version2LicenseDecoder.java:114)
at com.atlassian.extras.decoder.api.AbstractLicenseDecoder.decode(AbstractLicenseDecoder.java:15)
at com.atlassian.extras.decoder.api.DelegatingLicenseDecoder.decode(DelegatingLicenseDecoder.java:30)
at com.atlassian.extras.core.DefaultLicenseManager.decodeLicense(DefaultLicenseManager.java:62)
at com.atlassian.extras.core.DefaultLicenseManager.getAtlassianLicense(DefaultLicenseManager.java:50)
at com.atlassian.extras.core.DefaultLicenseManager.getLicense(DefaultLicenseManager.java:39)
at com.atlassian.jira.license.LicenseDetailsFactoryImpl$JiraProductLicenseManager.getProductLicense(LicenseDetailsFactoryImpl.java:132)
at com.atlassian.jira.license.LicenseDetailsFactoryImpl.getLicense(LicenseDetailsFactoryImpl.java:70)
at com.google.common.collect.Iterators$6.transform(Iterators.java:829)
at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:52)
at com.atlassian.jira.license.JiraLicenseManagerImpl$CachedLicenses.<init>(JiraLicenseManagerImpl.java:404)
at com.atlassian.jira.license.JiraLicenseManagerImpl$CachedLicenses.<init>(JiraLicenseManagerImpl.java:392)
at com.atlassian.jira.license.JiraLicenseManagerImpl.loadLicenses(JiraLicenseManagerImpl.java:389)
at com.atlassian.cache.memory.MemoryCacheManager$1.load(MemoryCacheManager.java:130)
at com.atlassian.cache.memory.MemoryCacheManager$1.load(MemoryCacheManager.java:106)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3576)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2318)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2191)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2081)
at com.google.common.cache.LocalCache.get(LocalCache.java:4019)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4042)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5024)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5031)
at com.atlassian.cache.memory.DelegatingCachedReference.getUnderLock(DelegatingCachedReference.java:102)
at com.atlassian.cache.memory.DelegatingCachedReference.get(DelegatingCachedReference.java:87)
... 21 more
Caused by: java.lang.RuntimeException: Signature verification failed
at com.atlassian.extras.keymanager.KeyManager.verify(KeyManager.java:141)
at com.atlassian.extras.decoder.v2.Version2LicenseDecoder.checkAndGetLicenseText(Version2LicenseDecoder.java:212)
... 46 more
Caused by: java.security.SignatureException: Invalid encoding for signature
at java.base/sun.security.provider.DSA.engineVerify(DSA.java:346)
at java.base/sun.security.provider.DSA.engineVerify(DSA.java:292)
at java.base/java.security.Signature$Delegate.engineVerify(Signature.java:1416)
at java.base/java.security.Signature.verify(Signature.java:790)
at com.atlassian.extras.keymanager.KeyManager.verify(KeyManager.java:139)
... 47 more
Caused by: java.io.IOException: Sequence tag error
at java.base/sun.security.util.DerInputStream.getSequence(DerInputStream.java:322)
at java.base/sun.security.provider.DSA.engineVerify(DSA.java:336)
... 51 more
Actually this will be changed a bit:
DELETE /rest/api/2/version/{id}
will be changed to get the semantics of POST /rest/api/2/version/{id}/removeAndSwap
while the latter will become deprecated
@AndrzejKotas : Could we please have an official documentation page instead of keep posting on a message thread?