How to update your add-on
Backend changes
One of the exciting changes with this release is the new JDK minimum requirement of 1.8, that allows you to use a wide new array of language features in your add-on code. While Stash 3.x supports running on Java 8; Bitbucket Server supports compiling to Java 8.
The largest change was we renamed our package namespace from com.atlassian.stash
to com.atlassian.bitbucket
, but this should also be a simple change when you update your plugins. The Bitbucket Server team updated over 100 add-ons internally and the process was quite straightforward using refactoring support in modern IDEs.
In addition to the repackage, we've also removed all @deprecated APIs from the codebase. Most of these had existing replacement methods in place, but some were removed without replacement. You can consult the latest Stash 3.x documentation for details on what replacement method to use if the new method is not obvious.
Finally, several of our bundled plugins were exporting API (our com.atlassian.stash:stash-build-integration
plugin, for example), which meant plugin developers added dependencies on that jar. However, only a small portion of the code in that jar was exported. This was a frequent source of plugin issues because plugin developers attempted to use our internal classes. In 4.0, the exported APIs from all of our plugins have been extracted into separate modules (like with the stash-build-integration
example, the build API is now in com.atlassian.bitbucket.server:bitbucket-build-api
). These new API modules contain all of the code that is published for plugin developers to use.
Front-end changes
Our Javascript and Soy API modules have moved to the Bitbucket namespace. AMD Modules, previously found under stash/api/*
, are now bitbucket/*
. Non-API modules will be under bitbucket/internal
. For example, stash/api/util/navbuilder
is now bitbucket/util/navbuilder
. For API Soy templates, these are now also under the bitbucket
namespace - Stash.template.branchSelector
is now bitbucket.component.branchSelector
.
Another front-end change is that most keys – including Form Fragments, Web Panel & Section locations, and Web Resource add-ons – have been moved to Bitbucket namespaces. There is more detail on these changes below.
Any methods or modules that were deprecated for removal in 4.0 have been removed.
How to update your add-on
The add-on key of your plugin must not change
The value of your add-on key, as defined within the atlassian-plugin.xml file, must not change. This is often defined in terms of the maven groupId and artefactId of your plugin. This value is used by Atlassian Marketplace and other parts of Bitbucket Server as a unique identifier for your plugin. Changing this value could lead to data loss, and will cause you to lose review and download history on the Atlassian Marketplace.
For example, you would replace the variables below with the values for groupId and artifactId in your pom.xml.
<atlassian-plugin key="${project.groupId}.${project.artifactId}" ...
Update your pom.xml file to reference the latest version of the Bitbucket Server 4.0. You will need to update version properties for both Bitbucket Server and AMPS, which currently requires a pre-release version to build Bitbucket Server plugins, as well as dependencies on any API artifacts.
<dependency> <groupId>com.atlassian.bitbucket.server</groupId> <artifactId>bitbucket-api</artifactId> <version>${bitbucket.version}</version> <scope>provided</scope> </dependency> ... <properties> <bitbucket.version>4.0.0</bitbucket.version> <bitbucket.data.version>${bitbucket.version}</bitbucket.data.version> <amps.version>6.1.0</amps.version> ... </properties>
In your pom.xml you will also need to change or add configuration for the
bitbucket-maven-plugin
(depending on whether you are supporting both Stash and Bitbucket Server, or just Bitbucket Server):<build> <plugins> <plugin> <groupId>com.atlassian.maven.plugins</groupId> <artifactId>bitbucket-maven-plugin</artifactId> <version>${amps.version}</version> <extensions>true</extensions> <configuration> <products> <product> <id>bitbucket</id> <instanceId>bitbucket</instanceId> <version>${bitbucket.version}</version> <dataVersion>${bitbucket.data.version}</dataVersion> </product> </products> </configuration> </plugin> </plugins> </build>
Update your add-on's name and description in pom.xml to reference "Bitbucket" instead of "Stash". For example:
<name>Bitbucket Server - Realtime Editor</name> <description>Provides support for real-time collaborative editing.</description>
Optional: If your plugin will only support Bitbucket Server, remove any Stash dependencies
<groupId>com.atlassian.stash</groupId> <artifactId>stash-api</artifactId>
- For a class with compilation errors, first remove any
com.atlassian.stash
import statements that are red. - Use the suggested imports your IDE provides, and/or consult the API Changelog and table below.
- Open the
atlassian-plugin.xml
inside your IDE- Rename any
com.atlassian.stash
imported components tocom.atlassian.bitbucket
(or equivalent as mentioned in the API changelog) - If you are using any web-resources with a dependency on
com.atlassian.stash.stash-web-api
, change them tocom.atlassian.bitbucket.server.bitbucket-web-api
- Check for any other changes in your resources required due to renamed frontend API
- Rename any
If your add-on has JavaScript which uses the Stash JavaScript API, change your AMD module imports from
stash/api/*
tobitbucket/*
Test the add-on starts in Bitbucket Server using:
mvn clean bitbucket:debug
Other helpful resources
- Bitbucket Server developer documentation.
- Ask a question on Atlassian Answers, using the "bitbucket-server" topic.
- Review the End of support announcements to ensure that you're aware of updates to this policy.
Outline of API changes
Java packages
Stash 3.x | com.atlassian.stash |
---|---|
Bitbucket 4.x | com.atlassian.bitbucket |
Add-on Key (in atlassian-plugin.xml)
Stash 3.x | <atlassian-plugin key="${project.groupId}.${project.artifactId}" ...> or <atlassian-plugin key="com.myorg.stash.awesome-plugin" ...> |
---|---|
Bitbucket 4.x | <atlassian-plugin key="com.myorg.stash.awesome-plugin" ...> (must not change in either case) <atlassian-plugin key="com.myorg.stash.awesome-plugin" ...> |
Maven plugin
Stash 3.x | <artifactId>maven-stash-plugin</artifactId> e.g.
|
---|---|
Bitbucket 4.x | <artifactId>bitbucket-maven-plugin</artifactId> e.g.
|
Exceptions
Stash 3.x | com.atlassian.stash.exception.ServiceException |
---|---|
Bitbucket 4.x |
The monolithic |
Java User model
Stash 3.x | com.atlassian.stash.user.StashUser |
---|---|
Bitbucket 4.x | com.atlassian.bitbucket.user.ApplicationUser |
Java Authentication Context
Stash 3.x | com.atlassian.stash.user.StashAuthenticationContext |
---|---|
Bitbucket 4.x | com.atlassian.bitbucket.auth.AuthenticationContext |
Java Event model
Stash 3.x | com.atlassian.stash.event.StashEvent |
---|---|
Bitbucket 4.x | com.atlassian.bitbucket.event.ApplicationEvent The monolithic |
Java model
Stash 3.x |
|
---|---|
Bitbucket 4.x |
We've standardized our naming:
All classes and interfaces with What was formerly a |
Java Pull Request Participant model
Stash 3.x |
|
---|---|
Bitbucket 4.x |
|
Soy templates
Stash 3.x | changeset |
---|---|
Bitbucket 4.x | commit |
Application constants
Stash 3.x |
|
---|---|
Bitbucket 4.x | com.atlassian.bitbucket.Product
|
License changes
Stash 3.x | com.atlassian.extras.api.stash.StashLicense |
---|---|
Bitbucket 4.x | com.atlassian.extras.api.bitbucket.BitbucketServerLicense Add this dependency to your POM:
|
Javascript API modules
Stash 3.x | stash/api/* (eg. stash/api/util/server ) |
---|---|
Bitbucket 4.x | bitbucket/* (eg. bitbucket/util/server ) |
Soy API namespaces
Stash 3.x | stash.template.branchSelector |
---|---|
Bitbucket 4.x | bitbucket.component.branchSelector |
Web API plugin module
Stash 3.x | com.atlassian.stash.stash-web-api |
---|---|
Bitbucket 4.x | com.atlassian.bitbucket.server.bitbucket-web-api Note there have been a number of new API resources added, which allow you to better express your web resources dependencies. Please see the updated Web UI API documentationfor more detail about these resources. |
Core web plugin module
Stash 3.x | com.atlassian.stash.stash-web-plugin |
---|---|
Bitbucket 4.x | This core plugin contains internal modules only and should not be referenced by other plugins. |
Web Panel & Section Locations
Stash 3.x |
e.g. |
---|---|
Bitbucket 4.x |
e.g. |
Web Resource Contexts
Stash 3.x |
e.g. |
---|---|
Bitbucket 4.x | bitbucket.*
|
Plugin decorators
Stash 3.x |
|
---|---|
Bitbucket 4.x | bitbucket.*
|
Web Resource Modules
Stash 3.x | <stash-resource/> |
---|---|
Bitbucket 4.x |
Note that |
Web Item icons (in atlassian-plugin.xml)
Stash 3.x | <param name="stashIconClass">...</param> |
---|---|
Bitbucket 4.x | <param name="iconClass">...</param>
|
Web I18n
Stash 3.x | stash_i18n |
---|---|
Bitbucket 4.x |
|
Form Fragments
Stash 3.x | stash.* |
---|---|
Bitbucket 4.x | bitbucket.* |
Javascript Events
Stash 3.x | stash.* |
---|---|
Bitbucket 4.x |
See below for additional information about JavaScript events. |
I18n keys
Stash 3.x | stash.* |
---|---|
Bitbucket 4.x | bitbucket.* |
Java API - Guava
Stash 3.x | com.google.common.base.Function/Predicate Guava 11 was available to plugins |
---|---|
Bitbucket 4.x | Java 8 Lambdas Guava types like Function or Predicate are no longer used in API type signatures, use the corresponding types from java.util.function instead Guava 18 is available to plugins |
Servlet Dependency
Stash 3.x | <groupId>javax.servlet</groupId> |
---|---|
Bitbucket 4.x | <groupId>javax.servlet</groupId> The artifactId has changed to javax.servlet-api from servlet-api. |
Branch permissions
Stash 3.x | canDelete, canWrite search |
---|---|
Bitbucket 4.x | hasPermission Checking for access to a The |
Exported 3rd party libraries
Stash 3.x | Apache HTTP Client 3.x is no longer exported by the host app. |
---|---|
Bitbucket 4.x | Use HTTP Client 4.x instead
|
SAL Scheduler deprecated
Stash 3.x |
com.atlassian.sal.api.scheduling.PluginScheduler (Since Bitbucket 4.0.0 will throw an IllegalArgumentException if any job data passed to scheduleJob does not implement java.io.Serializable) |
---|---|
Bitbucket 4.x |
Use
instead. |
Outline of changes made to the REST API
The payloads for some of the REST resources have changed. All URLs are the same except that the default context path is now /bitbucket
instead of /stash
.
Self Links
Some REST model classes, like RestStashUser
, had their "self" links defined two ways:
"link": {
"url": "/users/admin",
"rel": "self"
},
"links": {
"self": [
{
"href": "http://localhost:7990/stash/users/admin"
}
]
}
The "link"
attribute is from 1.0 and was deprecated in 2.11. From 4.0, the "link"
attribute has been removed. The "self"
entry in the "links"
map remains.
Changeset
to Commit
Ref output, such as branches and tags, had a "latestChangeset"
attribute. The following output is from the /projects/KEY/repos/slug/branches
resource:
{
"size": 1,
"limit": 1,
"isLastPage": false,
"values": [
{
"id": "refs/heads/search/STASHDEV-8813-search",
"displayId": "search/STASHDEV-8813-search",
"latestChangeset": "de307ea7b6abfa1aad8de6771d79da0a9a7fd3cb",
"latestCommit": "de307ea7b6abfa1aad8de6771d79da0a9a7fd3cb",
"isDefault": false
}
],
"start": 0,
"nextPageStart": 1
}
A "latestCommit"
attribute was added in 3.7 and "latestChangeset"
was deprecated. It has been removed in 4.0. This also applies to pull request refs.
AttributeMap
to PropertyMap
Some REST objects, most notably RestPullRequest
, had an "attributes"
attribute which allowed plugin developers to attach arbitrary data. However, the model for this was very restrictive, being defined in AttributeMap
as Map<String, Set<String>>
. In 3.2, PropertyMap
, defined as Map<String, Object>
, was added to replace the attribute support. However, for performance and API consistency reasons, most existing attributes were not converted over. In 4.0, the changeover is now complete.
The following JSON snippets show the old and new layouts for pull request properties.
As you can see, the new "properties"
map allows its numeric entries to be numeric, resulting in much more readable, useful output.
PullRequestOrder
default order
The getDefaultOrderForState(PullRequestState state)
method in PullRequestOrder
has been replaced withgetDefaultOrder()
, which always returns PullRequestOrder.NEWEST
.
XSRF Protection enabled by default
To prevent a malicious hacker submitting a form from a foreign site to a stash instance, XSRF protection has now been enabled by default on all REST resources which do not accept the "application/json" Content-Type.
Any client POSTing to these resources will need to add a special header to disable this check.
Header name | Header value |
---|---|
X-Atlassian-Token | no-check |
For example, to set a Project Avatar via curl, the following command can be used:
$ curl -X POST -u username:password -H "X-Atlassian-Token: no-check" http://localhost:8080/rest/api/1.0/projects/TEST/avatar.png -F avatar=@avatar.png
The -H "X-Atlassian-Token: no-check"parameter was not needed in 3.x, however is now needed since 4.0
For your own REST resources which do not accept "application/json" (e.g. multipart/form-data, plain/text etc), you can opt-out of XSRF protection by using the @XsrfProtectionExcluded annotation.
If you use the excluded annotation, it should be because your endpoint has some other type of protection against XSRF/CSRF attacks.
Javascript Events
Since Stash 3.0 we have provided a Javascript API module for creating and consuming events (stash/api/util/events
, now bitbucket/util/events
), however we haven't documented what events Bitbucket (Stash) emits as part of our Developer Docs. Which events should be used and which should be considered internal implementation details were subject to change.
We are actively looking at which events we should consider part of the API. We will document usage and guarantee the stability for events that are part of the API for a major version. We would like to hear any feedback on which events you make use of in your add-ons, and why, to aid in our consideration of what to consider for the JS Events API.
Add-on update strategies
There are two primary strategies we are suggesting to update your add-on, and here we explain how to implement each and how to provide support for your add-on going forward.
Hard break
The simplest way forward is to branch your add-on and only release Bitbucket Server 4.0 compatible versions in the future. Replace the old com.atlassian.stash dependency
with the new com.atlassian.bitbucket
one, fix the resulting compilation errors, and create a new listing on Marketplace.
Backwards/forwards compatibility
The best way to achieve this is to maintain a branch of the "Stash" version of your plugin, and merge changes onto a master branch which contains the "Bitbucket server" version.
Unfortunately, unless you have written a pure cross-product add-on, building two versions from the same branch of code is in general not worth the overhead.
Rename checklist
- Beware of changing any Strings which are used as keys for accessing data your add-on may store. e.g. namespaces used with
PluginSettingsFactory.createSettingsForKey
or prefixes used withApplicationPropertyService.getPluginProperty
- We strongly recommend that you do not change your add-on key; if you do, customers won't be able to see the updated version of your add-on in their Universal Plugin Manager. The default
atlassian-plugin.xml
generated by AMPS useskey="${project.groupId}.${project.artifactId}"
. Changing your MavengroupId
orartifactId
this will change your add-on key. If you are using ActiveObjects, you are strongly encouraged to set the
namespace
attribute to ensure the unique hash in your table names does not change. Otherwise anyone who has installed your plugin will "lose" all of their data when your plugin starts using new tables!
For example, here's how we defined the<ao/>
module in our ref sync plugin:<ao key="ao" namespace="com.atlassian.stash.stash-repository-ref-sync">