How to get licensing working for web-resources?

licensing
webresource

#1

I made my first bitbucket server plugin, and wanted to release it to the marketplace. It relies almost fully on static resources so I want these to be disabled unless the plugin is licensed.

Since there’s an example from Atlassian, this should be a trivial thing. https://developer.atlassian.com/platform/marketplace/ommitting-web-resources-for-unlicensed-server-apps/

However.

  1. Adding the class IsPluginLicensedCondition will cause an error on missing library.
  2. There is a reference to first completing https://developer.atlassian.com/platform/marketplace/adding-licensing-support-to-server-apps/ so I added the dependencies from there. This does not affect the result.
  3. Manually adding the plugin atlassian-plugins-webresource-api will make the class SimpleUrlReadingCondition available but it still wont compile, since it’s now lacking the class com.atlassian.plugin.web.baseconditions.BaseCondition.
  4. Manually adding the plugin atlassian-plugins-webfragment will make the addon compile, but deploying it throws error on missing requirement osgi.wiring.package
  5. Adding dependency spring-context will make it deployable, but now we instead get an error saying IsPluginLicensedCondition cannot be cast to com.atlassian.plugin.web.Condition
  6. This is where I’m stuck. :slight_smile:

Any help would be nice, I have no idea on how to go forward. I assume it’s something trivial that I’m missing and likely related to the outdated documentation that refers to use of @Scanner and earlier version of Spring. Maybe.


#2

Here’s an possibly related question using the same guide and also giving same errors. Problem with implementing UPM support into add-on


#3

I made an minimal example plugin. This compiles and can be deployed but throws the error on cast to com.atlassian.plugin.web.Condition


#4

The code that throws the error seem to actually test for both UrlReadingCondition as well as Condition, but the error message is always the same.

https://bitbucket.org/atlassian/atlassian-plugins-webresource/src/master/atlassian-plugins-webresource/src/main/java/com/atlassian/plugin/webresource/condition/UrlReadingConditionElementParser.java


#5

Thanks for the very handy code, @jan as I was able to consistently replicate the issue you’re facing. I was able to make your code work by having IsPluginLicensedCondition implement com.atlassian.plugin.web.Condition. Can you check it out if that suits your needs?

Cheers,
Ian


#6

Which dependency do I need to include to find it? Or can you directly share your working example? (PR?)

(also, this is contrary to what is suggested here: https://developer.atlassian.com/server/framework/atlassian-sdk/stateless-web-resource-transforms-and-conditions/ )


#7

No new dependencies needed. Here are the changes in the class:

import com.atlassian.plugin.web.Condition;

public class IsPluginLicensedCondition extends SimpleUrlReadingCondition implements Condition

and then I implemented an inherited abstract method like this

@Override
public boolean shouldDisplay(Map<String, Object> context) {
	// TODO Auto-generated method stub
	return false;
}

Those are the only changes I made. I opted to put the changes here (and not via PR) in order to help other members of the community who might face the same issue.

Regarding

(also, this is contrary to what is suggested here: https://developer.atlassian.com/server/framework/atlassian-sdk/stateless-web-resource-transforms-and-conditions/ )

I am not sure what changed, if there are any, (maybe SimpleUrlReadingCondition used to implement Condition?) but based on the stack trace, it points me in the direction that the condition has to be a com.atlassian.plugin.web.Condition. If this worked for your use case, the next step is to fix the documentation in https://developer.atlassian.com/server/framework/atlassian-sdk/stateless-web-resource-transforms-and-conditions/ by filing a document improvement request by clicking the Give docs feedback link on the upper right-hand side of the page.


#8

Ok, I implemented the Condition method shouldDisplay (I assume you pasted wrong code snippet in your answer?). This compiles and I can deploy the plugin. I tested that returning true vs false will do the proper thing.

If you look on the code of UrlReadingConditionElementParser.java, it looks like the Condition class should not be needed but the error message will always say that, even if the first cast fails.

The next problem is that I can’t seem to get DI working in this setup. I would prefer a super-simple version that I only inject PluginLicenseManager as per the example in adding-licensing-support-to-server-apps .

Please see the latest state of my github repo (note that the commits are intentionally separated to make somewhat sense). The error I currently are locked in is:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atlassian.upm.api.license.PluginLicenseManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

#9

You are correct, @jan, I am referring to Condition#shouldDisplay. I already edited my previous comment. After getting your latest changes, I can no longer install the app. It seems you removed the plugin components; tests are failing too.

Edit:
Also, I noticed that you’re not utilizing QuickReload, in which I assume you stop and run atlas-run everytime you have changes. To you use quickreload, kindly add enableQuickReload in your pom file like

<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>
        <enableQuickReload>true</enableQuickReload>
		<enableFastdev>false</enableFastdev>
		...
</plugin>

Having this, you need not stop the app you just need to

  1. open a new terminal
  2. go to the project directory
  3. Run atlas-package
  4. Once #3 is done, go back to the previous terminal where atlas-run is still running and check the logs as QuickReload kicks in.

#10

Hey @iragudo, if you check the latest version it should build and deploy (I removed the tests as well), but it will fail to activate since dependency injection doesn’t seem to work (and it’s unclear for me how to get it working). Can you please see if you can find a solution for that?

Thanks for the tip on Quickreload. I’m actually running atlas-run in one terminal and then atlas-cli + pi in another for quick deployments. I’ll look into this later.


#11

Getting your latest code, I still cannot install it. I changed your the POM and removed the two dependencies commented with

Needed for IntelliJ to resolve xxx

ran atlas-clean then atlas-run in the terminal, then it works fine. Checking UPM, all modules were loaded.

Can you try it out if that works for you? Thanks.


#12

I can confirm this works, one time. Trying to redeploy the plugin it will fail. Also running with newer bitbucket atlas-run-standalone --product bitbucket it will not allow deployment, but throws an error.

	... 63 frames trimmed
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atlassian.upm.api.license.PluginLicenseManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
	... 54 common frames omitted

#13

Hi @jan,

It seems to be ok on my end when I ran atlas-run-standalone --product bitbucket and upload the JAR file.

Trying to redeploy via QuickReload, by running atlas-package on a different terminal also was successful in redeploying the app. The only changes I made were to remove the two dependencies, and enable QuickReload in the POM.

EDIT:
For reference, my standalone version is 5.10.0 when I run atlas-run-standalone --product bitbucket.


#14

Thanks @iragudo

I disabled those two dependencies and enabled quickreload and now things are working properly. I pushed the last changes to github if someone else need it, basically, once the plugin is licensed the main view in bitbucket will have a green background on the logo. (to be tested with time bomb licenses)

This can now be marked as solved!