Broken Boilerplate for intermediate blueprint plugin

Greetings,

we just installed Confluence Server Edition and want to shape it fitting our workflow. Sadly it doesn’t seem as easy as i expected.

Currently i need to create a ‘intermediate’ blueprint. Nothing special. All we want is a simple blueprint with its own template and name. Also the current date should be inserted into the title (just like the meeting notes-blueprint). But i didn’t even get to this point…

I followed the beginner tutorial and created a basic blueprint without any context provider nor java code. Worked as expected. After that i went on to the intermediate tutorial and tried to create a context provider.

I can’t follow the tutorial anymore since it seems like it uses some old confluence-create-content-plugin. Also the created plugin boilerplate already includes some java-code splitted into impl and api. I tried to work around this issue and follow the guide, but wasn’t able to get it working.

To get a better idea of a working code example i found (or so i though…?) the source of the meeting notes-blueprint on bitbucket. https://bitbucket.org/atlassian/confluence-business-blueprints/src/84b86c46d457?at=master But a cloned repo does also not run via atlas-run.

Next i tried to use the atlas-sdk scripts to create a clean plugin and blueprint boilerplate. So i used atlas-create-confluence-plugin to create my plugin (which works), followed by atlas-create-confluence-plugin-module and selected the option blueprint. Also added a ContextProvider via the interactive script. And guess what? It doesn’t work. Seems like the Script creates also a ‘old’ version of ContextProvider-Blueprint since atlas-run fails with package com.atlassian.confluence.plugins.createcontent.api.contextproviders does not exist.

All i was able to find about this issue are old threads without a working solution, people telling each other how bad the confluence-guides are and some info about using Spring-Scanner instead of the broken create-content-plugin. (I would provide links to my found threads, but i am not allowed to post more links.)

I was redirected to the README-file of the used Spring-Scanner in Confluence but can’t wrap my head around how to use it in my ‘simple’ blueprint.

I really didn’t though that this will need so much work. All i want is the current Date in the Page Title to make the confluence experience for my coworkers as pleasant as possible…

Usually the solution is simple, truth is confluence can be bitchy until you master it.
Truth is though I can’t reproduce your error with confluence 5.8.8.
To me it sounds like an OSGi issue, please take a look on your pom.xml, in the section of plugins, in the artifact maven-confluence-plugin, especially the Import-Package section.
It should be looking like

<Import-Package>
    org.springframework.osgi.*;resolution:="optional",
    org.eclipse.gemini.blueprint.*;resolution:="optional",
    com.atlassian.plugin.osgi.bridge.external,
    com.atlassian.confluence.plugin.descriptor.web.conditions.user;resolution:="optional",
    com.atlassian.confluence.plugin.descriptor.web.conditions;resolution:="optional",
    com.atlassian.confluence.mail.notification.actions;resolution:="optional",
    com.atlassian.confluence.pages.persistence.dao.*;resolution:="optional",
    *;resolution:=optional
</Import-Package>

Now, add the com.atlassian.confluence.plugins.createcontent.api.contextproviders in the section, just like rest of entries and ensure that the dependency confluence-create-content-plugin has scope provided.
If that won’t work, please make some github so i can check it.

Thank you for your help.

Indeed, confluence feels bitchy. But i managed to archive ‘something’?

I created a new plugin, followed the beginner guide to create u dumb blueprint. Worked out fine. I deleted the impl and api folder and placed my BlueprintContextProvider.java there.

I tried something simple first: blueprintContext.put("vName", "TestUserName"); to test my ‘structure’. First i got failing Maven-Unit-Tests. So i deleted the test-files in the test-dir. Still: Tests failing… Some googling later i am starting the test-server via atlas-run -DskipTests=true -Dmaven.test.skip=true (is it somehow possible to disable the maven tests till use them globally?). Anyway, my simple Variable Function worked.

Now i wanted to create what i was trying to archive: Put the current date into the Site-Title.

As best as i could i tried to copy the official meeting-notes blueprint (Bitbucket) Worked out every thrown error. Now atlas-run -DskipTests=true -Dmaven.test.skip=true starts without a problem. No ERROR message or Warnings. But when log into confluence the blueprint plugin does’nt load. This add-on couldn't be loaded. It has one or more errors that prevent it from being enabled. Where can i find the error-log, or what can cause this?

Maybe my BlueprintContextProvider.java-file can help out: package com.domain.confluence.plugins.bautagebuch;import com.atlassian.confl - Pastebin.com It sits in ../src/main/java/com/domain/confluence/plugins/.

Greetings

by doing atlas-run -DskipTests=true as you did.

The output of atlas-run should contain the cause. Otherwise you are looking for catalina.out file. Generally speaking catalina.out and atlassian-confluence.log are your sources of logging.

Without looking on the tutorial you followed… add @Scanned in your class, @ComponentImport in
whatever you DI and @Inject in the constructor. Your class should look like:

@Scanned
public class BautagebuchContextProvider extends AbstractBlueprintContextProvider {
   @ComponentImport
    private LocaleManager localeManager;
   @ComponentImport
    private final I18NBeanFactory i18NBeanFactory;
   @ComponentImport
    private final UserAccessor userAccessor;
   @ComponentImport
    private final FormatSettingsManager formatSettingsManager;
 
   @Inject
    public BautagebuchContextProvider(LocaleManager localeManager,
                                      I18NBeanFactory i18NBeanFactory,
                                      UserAccessor userAccessor,
                                      FormatSettingsManager formatSettingsManager) {
        this.localeManager = localeManager;
        this.i18NBeanFactory = i18NBeanFactory;
        this.userAccessor = userAccessor;
        this.formatSettingsManager = formatSettingsManager;
    }

I am not quite sure if i18nbeanfactory needs it. Improvise :slight_smile:

Thank you Panos once again.

I played with @ComponentImport and @Inject and was able to understand the needed basics to get it working (Blueprint with String-Date in the Title).

For my last magic trick i need to get the current Space Name and place it into the document. Sadly i need help once again.

I searched through the javadoc and found some classes which return the space-name e.g.: SpaceContentEntityObject (Atlassian Confluence 5.9.2 API) or Spaced, GlobalHelper, …

But i always get the same error: non-static method getSpace() cannot be referenced from a static context. I am not really into object-oriented-programming, but i though that this could fix it:

@Scanned
public class BautagebuchContextProvider extends AbstractBlueprintContextProvider {
    [...]
    @ComponentImport
    private final GlobalHelper globalHelper;

    @Inject
    public BautagebuchContextProvider(LocaleManager localeManager,
                                      [...]
                                      GlobalHelper globalHelper,
                                      [...]) {
        [...]
        this.globalHelper = globalHelper;
    }

Sadly it only results into a timeout while loading the plugin (while starting the tomcat server for confluence) till the plugin gets skipped after 25 seconds. Is the some function i can use in a static context, or do i only need a little snippet again, which i am missing out? :slight_smile:

As reference my current code: http://pastebin.centos.org/521356/

Greetings

Step 1) Change the GlobalHelper with
com.atlassian.confluence.web.context.HttpContext.HttpContext
Step 2) Get the ThemeContext:
ThemeContext themeContext = ThemeContext.get(httpContext.getRequest());
Step 3) Get the space(key) by
themeContext.getSpace() / themeContext.getSpaceKe()
Step 4)
Profit and accept the answer :smiley:

I really would like to press that that “accept the answer” button, but i think i need one last step :smiley:

I imported HttpContext and ThemeContext, added HttpContext via:

    @ComponentImport
    private final HttpContext httpContext;

    @Inject
    public BautagebuchContextProvider(LocaleManager localeManager,
                                      [...]
                                      HttpContext httpContext,
                                      [...]) {
        [...]
        this.httpContext = httpContext;
    }

and tried to get the spacename with:

        ThemeContext themeContext = ThemeContext.get(httpContext.getRequest());
        Space space = themeContext.getSpace();
        String spaceName = space.getName();

        blueprintContext.put("vSpaceName", spaceName);

which resulted in a javax.servlet.http.HttpServletRequest not found error. After some googling i added the following to my pom.xml-file:

        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.3</version>
          <scope>provided</scope>
        </dependency>

The Plugin now compiles, but i can’t use the blueprint in confluence: We can't create that blueprint right now.. Also no Error-Output in the console. As soon as i remove the quoted snippets, everything works fine. (I also tried the newest version of javax.servlet e.g. 2.5)

Thank you again Panos!

… if you want to see the whole ContextProvider: http://pastebin.centos.org/523271/

Edit: When i try a different approach:

        ThemeContext themeContext = ThemeContext.get(httpContext.getRequest());
        String spaceKey = themeContext.getSpaceKey();
        Space space = new Space(spaceKey);
        String spaceName = space.getName();

        blueprintContext.put("vSpaceName", spaceName);

i don’t get any errors, but the variable field stays blank :confounded:


Edit2: Okay, i just got it working… Somehow i was not able to retrieve a proper SpaceKey (always blank). So i simply guessed and tried to interact with the given BlueprintContext:

        String spaceKey = blueprintContext.getSpaceKey();
        Space space = spaceManager.getSpace(spaceKey);
        String spaceName = space.getName();

        blueprintContext.put("vSpaceName", spaceName);

and it works! Sadly i really just guessed (after reading about generated PageID and the whole meaning of “context”. And since we are using java, i simply tried a function i often found in similar objects…

Can you link me the right documentation for this? I can’t find it and want to read about this blueprintContext. Also i want to give you the answer :wink:

I am sorry, i dont understand what you mean by “right documentation”.

Documentation for confluence is so sparsed, depending on version, plugin version and much more. example… confluence is a mix of spring and atlassian stuff where spring core is tied to atlassian needs. At least that’s my perception.

I also never used blueprints :slight_smile: