Bitbucket Server EAP - How to update your add-on

Error rendering macro 'viewport-redirect'

null

This is an early preview of an upcoming launch from Atlassian

We are sharing early, privileged information with you as a trusted partner of Atlassian. We ask that you keep this information private and not share it with any other third parties (except any trusted development partners) until the official launch.

This document and referenced resources are here to help reduce the time and effort needed on your part to make your add-on compatible with Bitbucket 4.0.

You should "watch" this page (press 'w') as we will be making updates to it as we receive feedback from our add-on developers and release subsequent EAPs.

 

About the changes

Bitbucket Server 4.0 is the biggest API release Bitbucket Server has ever seen. The decision to break so many add-ons with this release was not taken lightly. As developers, we understand the friction such changes can cause. However, we strongly believe this short term pain will be for long term gain with a clearer, cleaner, more consistent and more robust API in 4.0 and beyond. We are making quite a few large changes in this release in the interest of consistency, and with the strong hope that we will not need to make such a drastic change again anytime soon.

On this page

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 Bitbucket Server 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.bitbucket 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 Bitbucket Server 3.x documentationfor 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.bitbucket: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 - Bitbucket Server.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

There is no distribution or installer for the Bitbucket Server 4.0 EAP1 build as this is a developer pre-release. It is only available via Maven artifacts. By updating your add-on's pom.xml following the instructions below, Maven will download the Bitbucket Server artifacts.

 

  1. 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-eap1</bitbucket.version>
       <bitbucket.data.version>${bitbucket.version}</bitbucket.data.version>
       <amps.version>6.1.0-6cf99b0</amps.version>
       ...
    </properties>
  2. 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 Bitbucket Server 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>
  3. Update your add-on's name and description in pom.xml to reference "Bitbucket" instead of "Bitbucket Server". For example:

    <name>Bitbucket Server - Realtime Editor</name>
    <description>Provides support for real-time collaborative editing.</description>
  4. Optional: If your plugin will only support Bitbucket Server, remove any Bitbucket Server dependencies

    <groupId>com.atlassian.bitbucket</groupId>
    <artifactId>stash-api</artifactId>
  5. For a class with compilation errors, first remove any com.atlassian.bitbucket import statements that are red.
  6. Use the suggested imports your IDE provides, and/or consult the API Changelog and table below.
  7. Open the atlassian-plugin.xml inside your IDE
    1. Rename any com.atlassian.bitbucket imported components to com.atlassian.bitbucket (or equivalent as mentioned in the API changelog)
    2. If you are using any web-resources with a dependency on com.atlassian.bitbucket.stash-web-api, change them to com.atlassian.bitbucket.server.bitbucket-web-api
    3. Check for any other changes in your resources required due to renamed frontend API
  8. If your add-on has JavaScript which uses the Bitbucket Server JavaScript API, change your AMD module imports from stash/api/* to bitbucket/*

  9. Test the add-on starts in Bitbucket Server using:

    mvn clean bitbucket:debug

Other helpful resources

  • Bitbucket Server developer documentation. This link is to be quiet until launch of Bitbucket Server 4.0.
  • Live help via the Bitbucket Server EAP public HipChat room. Bitbucket developers and other add-on developers will be available here to help with issues or questions you may have.
  • As a last resort, you can create a support ticket in the SSP project, and mention you are using the Bitbucket Server 4.0 EAP.

Please do not create issues in the Bitbucket Server project on jira.atlassian.com or ask questions on Atlassian Answers in relation to the Bitbucket Server 4.0 EAP, as these are public forums.

Outline of API changes

 

AreaBitbucket Server 3.xBitbucket 4.x
Java packagescom.atlassian.bitbucketcom.atlassian.bitbucket
Maven
<artifactId>maven-stash-plugin</artifactId>
e.g.
<plugin>
 <groupId>com.atlassian.maven.plugins</groupId>
 <artifactId>maven-stash-plugin</artifactId>
 <version>${amps.version}</version>
 <extensions>true</extensions>
 <configuration>
   <products>
    <product>
     <id>stash</id>
     <instanceId>stash</instanceId>
     <version>${stash.version}</version>
     <dataVersion>${stash.data.version}</dataVersion>
    </product>  
   </products>
  </configuration>
</plugin> 
<artifactId>bitbucket-maven-plugin</artifactId>
e.g.
<plugin>
 <groupId>com.atlassian.maven.plugins</groupId>
 <artifactId>bitbucket-maven-plugin</artifactId>
 <version>6.1.0-6cf99b0</version>
 <extensions>true</extensions>
 <configuration>
  <products>
   <product>
    <id>bitbucket</id>
    <instanceId>bitbucket</instanceId>
    <version>${bitbucket.version}</version>
    <dataVersion>${bitbucket.version}</dataVersion>
   </product>  
  </products>
 </configuration>
</plugin> 
Exceptionscom.atlassian.bitbucket.exception.ServiceException

com.atlassian.bitbucket.ServiceException

The monolithic com.atlassian.bitbucket.exception package has been removed. The exceptions it previously contained have been moved into the module they belong to. For example, NoSuchRepositoryException is now in the com.atlassian.bitbucket.repository package.

Java User modelcom.atlassian.bitbucket.user.Bitbucket ServerUsercom.atlassian.bitbucket.user.ApplicationUser
Java Authentication Contextcom.atlassian.bitbucket.user.Bitbucket ServerAuthenticationContextcom.atlassian.bitbucket.auth.AuthenticationContext
Java Event model
com.atlassian.bitbucket.event.Bitbucket ServerEvent
com.atlassian.bitbucket.event.ApplicationEvent

The monolithic com.atlassian.bitbucket.event package has been broken down and the events it formerly contained have been moved into subpackages. For example, RepositoryCreatedEvent is now in com.atlassian.bitbucket.event.repository

Java model

Changeset, DetailedChangeset

Commit, Changeset

We've standardized our naming:

  • A "commit" is an event where the contents of a repository are changed
  • A "changeset" is the set of changes that exist between two commits
  • The codebase no longer uses the words "changeset" and "commit" interchangeably; each word refers to a specific concept

All classes and interfaces with Changeset in the name have replaced with an equivalent class or interface with Commit in the name instead.

What was formerly a DetailedChangeset, because the object that should have been called a Commit had already stolen the Changeset name, is now called a Changeset

Soy templateschangesetcommit
Application constants

com.atlassian.bitbucket.Product

  • #NAME="Bitbucket Server"
  • #DATA_CENTER_NAME="Bitbucket Data Center"
  • #FULL_NAME="Atlassian Bitbucket Server"

com.atlassian.bitbucket.Product

  • #NAME="Bitbucket"
  • #DATA_CENTER_NAME="Bitbucket Data Center"
  • #FULL_NAME="Atlassian Bitbucket"
Javascript API modulesstash/api/* (eg. stash/api/util/server)

bitbucket/* (eg. bitbucket/util/server)

Soy API namespacesBitbucket Server.template.branchSelectorbitbucket.component.branchSelector
Web API plugin module
com.atlassian.bitbucket.stash-web-api
com.atlassian.bitbucket.server.bitbucket-web-api
Core web plugin module
com.atlassian.bitbucket.stash-web-plugin

This core plugin contains internal modules only and should not be referenced by other plugins.

Web Panel & Section Locations

stash.*

e.g. stash.branch.list.actions.dropdown

bitbucket.*

e.g. bitbucket.branch.list.actions.dropdown

Web Resource Contexts

stash.*

e.g. stash.layout.pullRequest

bitbucket.*

bitbucket.layout.pullRequest

Web Resource Modules<stash-resource/>

<client-resource/>

Note that client-resource will expand <directory/> elements in-place, where stash-resource expanded them at the end.

Web I18nstash_i18n

getTextgetTextAsHtml

stash_i18n should not be used; getText is a cross-product replacement that doesn't accept a default translation parameter. See Writing Soy Templates for usage details.

Form Fragmentsstash.*bitbucket.*
Javascript Eventsstash.*

bitbucket.internal.*

See below for additional information about JavaScript events.

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.

Some REST model classes, like RestBitbucket ServerUser, 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
}

"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.

Bitbucket Server
  "attributes": {
    "resolvedTaskCount": [
      "0"
    ],
    "openTaskCount": [
      "1"
    ],
    "commentCount": [
      "2"
    ]
  }
Bitbucket Server
  "properties": {
    "commentCount": 2,
    "openTaskCount": 1,
    "resolvedTaskCount": 0
  }

As you can see, the new "properties" map allows its numeric entries to be numeric, resulting in much more readable, useful output.

Javascript Events

Since Bitbucket Server 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 (Bitbucket Server) emits as part of our Developer Docs. Which events should be used and which should be considered internal implementation details were subject to change.  

For this initial EAP, JS events have been renamed from stash.* to bitbucket.internal.*however 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.  These events will be renamed to bitbucket.* prior to the release of Bitbucket 4.0 to signify this support. 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.bitbucket dependency with the new com.atlassian.bitbucket one, fix the resulting compilation errors, and create a new listing on Marketplace.

Backwards/forwards compatibility

The second option is to add the new com.atlassian.bitbucket dependencies to the current branch of your plugin, alongside your existing com.atlassian.bitbucket dependencies, and have both Bitbucket Server 3.x and Bitbucket Server 4.x support going forward.

This can be achieved by using an "application" attribute on any modules you define in atlassian-plugin.xml. This way, only those modules compatible with "bitbucket" will start at runtime if running in Bitbucket Server 4.0, and only the "stash" modules will be started if running in Bitbucket Server.

For example, a component that has the same interface but different implementations for Bitbucket Server and Bitbucket.

<!-- Bitbucket component -->
<component key="bitbucketComponent" 
  name="myComponent"
  class="com.mycompany.plugin.BitbucketComponent"
  application="bitbucket">
  <interface>com.mycompany.plugin.Component</interface>
</component>

<!-- Bitbucket Server component -->
<component key="stashComponent" 
  name="myComponent"
  class="com.mycompany.plugin.Bitbucket ServerComponent" 
  application="stash">
  <interface>com.mycompany.plugin.Component</interface>
</component>

 

The benefits of this approach include keeping your add-on backward compatible with Bitbucket Server, and it also allows you to keep a single Marketplace listing for your add-on, and would be marked compatible with both Bitbucket Server and Bitbucket Server.

Rename checklist

  1. 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 with ApplicationPropertyService.getPluginProperty
  2. Beware of subtle, unexpected changes that can arise from changing your plugin's key, or its Maven groupId or artifactId
    1. The default atlassian-plugin.xml generated by AMPS uses key="${project.groupId}.${project.artifactId}", so changing your Maven groupId or artifactId will change your plugin key
    2. If you are using SAL's PluginUpgradeTask and  <param name="build">7</param> to upgrade your plugin between versions, changing your plugin key will result in all upgrades being run again–the build number is recorded against your plugin key, so your new plugin key is considered an all-new plugin
    3. If you haven't defined a namespace attribute on your <ao/> module, by default it uses your plugin key
  3. 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.bitbucket.stash-repository-ref-sync">
Last modified on Oct 6, 2017

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.