What dependency is the webwork library in?

Kirk Walek November 8, 2017

I am using the Atlassian plugin SDK to create a plugin. I am trying to import the following two classes:

import webwork.action.ServletActionContext;
import webwork.multipart.MultiPartRequestWrapper;

However, my IDE (IntelliJ) states that the symbol 'webwork' cannot be resolved. When I try building the plugin it has no problem building. But then when I import the plugin onto a server the pages that use the faulty import don't load, they instead return a 500 error.

 

My guess is that I don't have the right dependency in my maven file, but I was unable to figure what that dependency would be.

 

1 answer

1 accepted

2 votes
Answer accepted
Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 8, 2017

Hello,

Webwork is situated in webwork-1.4-atlassian-30.jar. I guess it comes from

<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>

Also add this dependency

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

I think that required dependencies were not imported in your project. Try to find the jar above in your IDE in external libraries. I think it does not exist. If it does not exist, then:

1. Check that you connected your project to the maven from atlassian sdk in your IDE. It must be explicitly set in your IDE because by default the  maven from IDE is used.

2. Go to the plugin folder in terminal and execute atlas-maven eclipse:eclipse (it does not matter if you use IDEA, just execute it). After it try to reimport maven dependencies in your IDE.

If it does not help, provide pom.xml, atlassian-plugin.xml and your webwork class

Kirk Walek November 9, 2017

[removed]

Kirk Walek November 9, 2017

[removed]

Kirk Walek November 9, 2017

[removed]

Kirk Walek November 9, 2017

Unfortunately this was not the solution (Though I may need more clarification on #1, I don't know much about maven projects). As requested, I will provide the three files (provided in next replies).

 

Thanks for the help. 

 

(to add clarification for outside readers, this comment started as an apology for possible notification spam because the reply kept getting deleted for an unknown reason. - They came back... I "removed" them)

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 9, 2017

@Kirk Walek

I do not know. That was your first reply I saw :) Keep replying. Do not worry.

Kirk Walek November 9, 2017

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.uic.plugins</groupId>
<artifactId>JiraRepos</artifactId>
<version>1.0</version>
<organization>
<name>Universal Instruments</name>
<url>http://www.uic.com/</url>
</organization>
<name>Jira Repositories</name>
<description>This is the com.uic.plugins:JiraRepos plugin for Atlassian JIRA.</description>
<packaging>atlassian-plugin</packaging>
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-runtime</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-jira-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<productVersion>${jira.version}</productVersion>
<productDataVersion>${jira.version}</productDataVersion>
<enableQuickReload>true</enableQuickReload>
<enableFastdev>false</enableFastdev>
<!-- See here for an explanation of default instructions: -->
<!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<!-- Add package to export here -->
<Export-Package>
com.uic.plugins.JiraRepos.api,
</Export-Package>
<!-- Add package import here -->
<Import-Package>
org.springframework.osgi.*;resolution:="optional",
org.eclipse.gemini.blueprint.*;resolution:="optional",
*
</Import-Package>
<!-- Ensure plugin is spring powered -->
<Spring-Context>*</Spring-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<scannedDependencies>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-external-jar</artifactId>
</dependency>
</scannedDependencies>
<verbose>false</verbose>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jira.version>7.2.2</jira.version>
<amps.version>6.2.11</amps.version>
<atlassian.spring.scanner.version>1.2.13</atlassian.spring.scanner.version>
<!-- This key is used to keep the consistency between the key in atlassian-plugin.xml and the key to generate bundle. -->
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
<!-- TestKit version 6.x for JIRA 6.x -->
<testkit.version>6.3.11</testkit.version>
</properties>
</project>
Kirk Walek November 9, 2017

atlassian-plugin.xml

<?xml version="1.0" encoding="UTF-8"?>

<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}" />
</plugin-info>
<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="JiraRepos"/>
<!-- add our web resources -->
<web-resource key="JiraRepos-resources" name="JiraRepos Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<resource type="download" name="JiraRepos.css" location="/css/JiraRepos.css"/>
<resource type="download" name="JiraRepos.js" location="/js/JiraRepos.js"/>
<context>JiraRepos</context>
</web-resource>
<web-section key="RepoSection" name="Dropdown Repositories Section" location="dropdown-link"/>
<web-item key="dropdown-link" name="Dropdown Repositories Link" section="system.top.navigation.bar">
<label>Repositories</label>
<link linkId="dropdown-link">/secure/Repositories.jspa?</link>
</web-item>
<web-item key="CreateRepoLink" name="Create A Repository Link" section="dropdown-link/RepoSection">
<label>Create a Repository</label>
<link linkId="create-link">/secure/Repositories.jspa?</link>
</web-item>
<webwork1 name="RepoActions" i18n-name-key="repo-actions.name" key="repo-actions">
<description key="repo-actions.description">The RepoActions Plugin</description>
<actions>
<action name="com.uic.plugins.JiraRepos.Pages.ReposPage" alias="Repositories">
<view name="create" type="velocity">/templates/create.vm</view>
<view name="login" type="velocity">/templates/login.vm</view>
</action>
</actions>
</webwork1>
</atlassian-plugin>
Kirk Walek November 9, 2017

webwork class

package com.uic.plugins.JiraRepos.Pages;

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.project.ProjectCategory;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.web.action.JiraWebActionSupport;

import com.uic.plugins.JiraRepos.BitBucket.BitBucketRest;
import com.uic.plugins.JiraRepos.Helpers.BasicTools;
import com.uic.plugins.JiraRepos.Helpers.Encrypter;
import com.uic.plugins.JiraRepos.Helpers.URLHelper;
import com.uic.plugins.JiraRepos.Jira.JiraTools;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.Collection;
import java.util.Map;

import webwork.action.ServletActionContext;
import webwork.multipart.MultiPartRequestWrapper;

// This class is used to pass information to and process input from
// a user on the 'Create Repository' web-page
public class ReposPage extends JiraWebActionSupport
{
// views
private static final String CREATE_PAGE = "create";
private static final String LOGIN_PAGE = "login";

// miscellaneous
static String CREDENTIAL_SPLIT = ":";
private static String WRITEREAD = "PROJECT_WRITE";
private static String READONLY = "PROJECT_READ";

// the user accessing this page
private ApplicationUser user;
// the user's BitBucket username
private String username;
// the user's encrypted BitBucket password
private String eac;
// username and password combined into one String
private String credentials;
// the name of the project
private String name;
// the abbreviation used to identify the project
private String key;
// a description of the project
private String description;
// the owner of the project
private String owner;
// a selected existing category
private String selectCategory;
// a newly entered category value
private String newCategory;
// the groups with write access
private String[] groupWrite;
// the groups with read access
private String[] groupRead;
// the users with write access
private String[] userWrite;
// the users with read access
private String[] userRead;
// an error handler for catching mistakes
private ReposErrors error;

// execute executes a web operation and then directs the user to the next view
@Override public String execute() throws Exception
{
// get the user performing the action
user = JiraTools.getCurrentUser();
// redirect to login if no user is found
if (user == null)
{
return forceRedirect(URLHelper.LOGIN_URL + URLHelper.REPOSITORY_URL);
}
// get the passed in information from the query string
HttpServletRequest request = getHttpRequest();
Map<String,String[]> parameters = request.getParameterMap();
username = BasicTools.safe3(parameters.get(URLHelper.USERNAME_QUERY));
eac = BasicTools.safe3(parameters.get(URLHelper.EAC_QUERY));
error = new ReposErrors();
// go to login page without errors if nothing is provided
if (username.equals(BasicTools.EMPTY) && eac.equals(BasicTools.EMPTY))
{
return LOGIN_PAGE;
}
// get credentials
String password = new Encrypter().unEncrypt(eac);
credentials = username + CREDENTIAL_SPLIT + password;
// if invalid BitBucket credentials are provided, return to login
error.verifyCredentials(credentials);
if (error.hasLoginError())
{
return LOGIN_PAGE;
}
// get remaining queries
name = BasicTools.safe3(parameters.get(URLHelper.NAME_QUERY));
key = BasicTools.safe3(parameters.get(URLHelper.KEY_QUERY)).toUpperCase();
description = BasicTools.safe3(parameters.get(URLHelper.DESCRIPTION_QUERY));
owner = BasicTools.safe3(parameters.get(URLHelper.OWNER_QUERY));
selectCategory = BasicTools.safe3(parameters.get(URLHelper.CATEGORY_SELECT_QUERY));
newCategory = BasicTools.safe3(parameters.get(URLHelper.CATEGORY_QUERY));
groupWrite= BasicTools.safe2(parameters.get(URLHelper.GROUP_WRITE_QUERY));
groupRead = BasicTools.safe2(parameters.get(URLHelper.GROUP_READ_QUERY));
userWrite= BasicTools.safe2(parameters.get(URLHelper.USER_WRITE_QUERY));
userRead = BasicTools.safe2(parameters.get(URLHelper.USER_READ_QUERY));
///////////////////////////////////////////////////////////////////////////////////////////////////////
// THE THING THAT I AM HOPING WILL WORK BUT I HAVE NO IDEA WHAT WILL ACTUALLY WORK //
///////////////////////////////////////////////////////////////////////////////////////////////////////
MultiPartRequestWrapper wrapper = ServletActionContext.getMultiPartRequest();
File file = wrapper.getFile(URLHelper.AVATAR_QUERY);
BasicTools.PLEASEDONTLEAVETHISPRINTINTHECODE(file.getPath());
///////////////////////////////////////////////////////////////////////////////////////////////////////
// check for no input
if (name.equals(BasicTools.EMPTY)
&& key.equals(BasicTools.EMPTY)
&& description.equals(BasicTools.EMPTY)
&& owner.equals(BasicTools.EMPTY)
&& selectCategory.equals(BasicTools.EMPTY)
&& newCategory.equals(BasicTools.EMPTY)
&& (groupWrite.length == 0)
&& (groupRead.length == 0)
&& (userWrite.length == 0)
&& (userRead.length == 0))
{
return CREATE_PAGE;
}
// check for errors
error.verifyDetails(credentials,name,key,description,owner);
error.verifyCategory(selectCategory,newCategory);
// redirect back to create page for any input errors
if (error.hasError())
{
return CREATE_PAGE;
}
// otherwise, create the desired repository and projects
createRepo();
// redirect back to create page for any unexpected errors
if (error.hasUnexpected())
{
return CREATE_PAGE;
}
return forceRedirect(URLHelper.projectPage(key));
}

// createRepo creates a new Repository with corresponding projects
private void createRepo()
{
// create BitBucket project
error.addUnexpected(BitBucketRest.projectPostRequest(credentials,name,key,description));
// create and configure BitBucket repository
error.addUnexpected(BitBucketRest.repoPostRequest(credentials,name,key));
error.addUnexpected(BitBucketRest.hookPutRequest(credentials,name,key));
// add group access permissions
error.addUnexpected(BitBucketRest.groupPutRequest(credentials,key,WRITEREAD,groupWrite));
error.addUnexpected(BitBucketRest.groupPutRequest(credentials,key,READONLY,groupRead));
// add user access permissions
error.addUnexpected(BitBucketRest.userPutRequest(credentials,key,WRITEREAD,userWrite));
error.addUnexpected(BitBucketRest.userPutRequest(credentials,key,READONLY,userRead));
// create and configure Jira project
ApplicationUser lead = ComponentAccessor.getUserManager().getUserByName(owner);
error.addUnexpected(JiraTools.createProject(name,key,description,lead));
// // TODO: GET THE SCRUM BOARD WORKING
// // create and configure scrum board
// error.addUnexpected(JiraTools.createBoard(user,key));
// add project category
error.addUnexpected(JiraTools.addCategory(key,selectCategory,newCategory));
}

// getters
public String getUsername()
{
return username;
}
public String getEac(){
return eac;
}
public String getName()
{
return name;
}
public String getKey()
{
return key;
}
public String getDescription()
{
return description;
}
public String getOwner()
{
return owner;
}
public String getSelectCategory()
{
return selectCategory;
}
public String getNewCategory()
{
return newCategory;
}
public String[] getGroupWrite()
{
return groupWrite;
}
public String[] getGroupRead()
{
return groupRead;
}
public String[] getUserWrite()
{
return userWrite;
}
public String[] getUserRead()
{
return userRead;
}
public Collection<String> getGroups()
{
return BitBucketRest.getGroups(credentials);
}
public Collection<String> getUsers()
{
return BitBucketRest.getUsers(credentials);
}
public Collection<ProjectCategory> getCategories()
{
return JiraTools.getCategories();
}
public ReposErrors getError()
{
return error;
}
}
Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 10, 2017

I tried to import the files you provided but there are a lot of files missing which embedded deeply in your code. Either make a simpler example or provide all files.

Cheers.

Kirk Walek November 13, 2017

Right... Sorry. I've made another plugin that focuses on what I'm struggling with. Here are the relevant files:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.uic.plugins</groupId>
<artifactId>Test</artifactId>
<version>1.0</version>
<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>
<name>Test</name>
<description>This is the com.uic.plugins:Test plugin for Atlassian JIRA.</description>
<packaging>atlassian-plugin</packaging>
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-runtime</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-jira-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<productVersion>${jira.version}</productVersion>
<productDataVersion>${jira.version}</productDataVersion>
<enableQuickReload>true</enableQuickReload>
<enableFastdev>false</enableFastdev>
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<!-- Add package to export here -->
<Export-Package>
com.uic.plugins.Test.api,
</Export-Package>
<!-- Add package import here -->
<Import-Package>
org.springframework.osgi.*;resolution:="optional",
org.eclipse.gemini.blueprint.*;resolution:="optional",
*
</Import-Package>
<!-- Ensure plugin is spring powered -->
<Spring-Context>*</Spring-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<scannedDependencies>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-external-jar</artifactId>
</dependency>
</scannedDependencies>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jira.version>7.2.2</jira.version>
<amps.version>6.2.11</amps.version>
<plugin.testrunner.version>1.2.3</plugin.testrunner.version>
<atlassian.spring.scanner.version>1.2.13</atlassian.spring.scanner.version>
<!-- This key is used to keep the consistency between the key in atlassian-plugin.xml and the key to generate bundle. -->
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
<!-- TestKit version 6.x for JIRA 6.x -->
<testkit.version>6.3.11</testkit.version>
</properties>
</project>

atlassian-plugin.xml

<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}" />
</plugin-info>
<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="Test"/>
<!-- add our web resources -->
<web-resource key="Test-resources" name="Test Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<resource type="download" name="Test.css" location="/css/Test.css"/>
<resource type="download" name="Test.js" location="/js/Test.js"/>
<context>Test</context>
</web-resource>
<web-item key="link" name="Link" section="system.top.navigation.bar">
<label>Test Me</label>
<link linkId="link">/secure/Test.jspa?</link>
</web-item>
<webwork1 name="Test Actions" i18n-name-key="test-actions.name" key="test-actions">
<description key="repo-actions.description">The TestActions Plugin</description>
<actions>
<action name="com.uic.plugins.Test.TestPage" alias="Test">
<view name="test" type="velocity">/templates/test.vm</view>
<view name="error" type="velocity">/templates/error.vm</view>
</action>
</actions>
</webwork1>
</atlassian-plugin>

webwork class

package com.uic.plugins.Test;

import com.atlassian.jira.avatar.Avatar;
import com.atlassian.jira.avatar.AvatarManager;
import com.atlassian.jira.avatar.Selection;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.icon.IconOwningObjectId;
import com.atlassian.jira.icon.IconType;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.project.ProjectManager;
import com.atlassian.jira.web.action.JiraWebActionSupport;
import webwork.action.ServletActionContext;
import webwork.multipart.MultiPartRequestWrapper;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class TestPage extends JiraWebActionSupport
{
private String message;

@Override public String execute() throws Exception
{
try
{
// get the user's submitted file from the form
MultiPartRequestWrapper wrapper = ServletActionContext.getMultiPartRequest();
File file = wrapper.getFile("avatar");
// get Jira components
AvatarManager avatarManager = ComponentAccessor.getAvatarManager();
ProjectManager projectManager = ComponentAccessor.getProjectManager();
// get data to create a new avatar
String path = file.getPath();
// this test assumes png format
String type = AvatarManager.PNG_CONTENT_TYPE;
IconType iconType = IconType.PROJECT_ICON_TYPE;
// this test assumes at least one project exists
Project project = projectManager.getProjectObjects().iterator().next();
IconOwningObjectId id = new IconOwningObjectId(project.getId().toString());
InputStream input = new FileInputStream(file);
// this test assumes the image is larger than 10x10
Selection selection = new Selection(0,0,10,10);
// create the avatar
Avatar avatar = avatarManager.create(path,type,iconType,id,input,selection);
message = avatar.getId().toString();
return "test";
}
catch (Exception e)
{
// set the message field for display
message = e.getMessage();
return "error";
}
}

public String getMessage()
{
return message;
}
}
Kirk Walek November 13, 2017

and the two view pages

test.vm

<body id="jira" class="aui-layout aui-theme-default aui-page-focused">
<div id="page">
<section id="content" role="main">
<div class="aui-page-panel">
<div class="aui-page-panel-inner">
<section class="aui-page-panel-content">
<h2>Get Avatar</h2>
<form class="aui" action="Test.jspa?">
<div style="width: 48%; float: left">
<fieldset>
<h4>Project Avatar</h4>
<div class="field-group">
<label for="avatar-field">Project Avatar:</label>
<input class="upfile" type="file" id="avatar-field" name="avatar">
</div>
<div>
$message
</div>
</fieldset>
<br>
</div>
<div class="buttons-container">
<div class="buttons">
<button class="aui-button aui-button-primary" style="float: right">Submit</button>
</div>
</div>
</form>
</section>
</div>
</div>
</section>
</div>
</body>

error.vm

<body id="jira" class="aui-layout aui-theme-default aui-page-focused">
<div id="page">
<section id="content" role="main">
<div class="aui-page-panel">
<div class="aui-page-panel-inner">
<section class="aui-page-panel-content">
<div style="width: 100%; padding: 5px; border: 1px solid #d04437; border-radius: 3px; margin-top: 10px;">
<h6 style="color: #d04437">Unexpected Error</h6>
$message
</div>
</section>
</div>
</div>
</section>
</div>
</body>
Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 15, 2017

Hello,

Sorry for late reply. I just tried it. All I changed was scope from compile to provided  atlassian-spring-scanner-annotation

        <dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>provided</scope>
</dependency>

And I deleted the following dependency

        <dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-runtime</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>runtime</scope>
</dependency>

That is all. Then I ran atlas-mvn clean package and istalled the jar. Everything worked. Actually it should have worked wihtout my changes but Jira sometimes could have got broken. At least on my Jira version.

Anyway what is your error?

Kirk Walek November 15, 2017

The error stated in the IDE is just "Cannot resolve symbol 'webwork'". This error appears in the two import lines: 

import webwork.action.ServletActionContext;
import webwork.multipart.MultiPartRequestWrapper;

 The error then propagates to where I try to use those two classes. Thinking it might just be an error with the IDE, I've run atlas-mvn package and successfully built the .jar file. However, when I install the plugin and go to the url (by clicking on the web-item), instead of loading the 'test' view which would signify a success, it loads the 'error' view. I had originally thought that the reason the two classes aren't importing properly was just because I didn't have the right dependencies, but now I have no clue.

 

I am trying to get some sort of a file upload system to work, so that a user can select an avatar for their project. It seemed to me I need to get the file through multi-part data, but I have so far not been able to.

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 15, 2017

I wrote you in the beginning what to do with ide. If you have done it then it should work by now.

Comment all lines in your  TestRun execute method except return "test". Build the package and install. You should see the test.vm view.

Kirk Walek November 15, 2017

for 2.) I have run the command atlas-mvn eclipse:eclipse the files .classpath and .project have been added to the project. Reimporting, rebuilding, and  reinstalling the plugin after this yields the same affect.

 

for 1.) I could use more information on this, I'm not sure I understand how to be certain I have done this properly. I have been able to use other dependencies such as the servlet-api which led me to believe the maven project was setup properly, but further instruction on this would be helpful.

 

If I comment out the other lines except return "test", yes it will load the page. The error occurs at lines 28 and 29 where the MultiPartRequestWrapper is being used. Commenting out the error is not a satisfactory solution.

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 15, 2017

Sure,  because you use it incorrectly. DoExecute works before your test.vm was shown and you chose a file to upload. How is it suppose to get the file you are trying to reference if you have not sent it yet? I will try to change your code later and post here. 

Kirk Walek November 15, 2017

yes please... thank you for the help

Kirk Walek November 15, 2017

for more clarification (if I understand your last point): wrapper.getFile("avatar") should return null when no file has been provided. This should then be caught by the try block and would explain why I'm unable to load the 'test' view. To fix this I could add a null check after line 29 which prevents the execute method from continuing if the file is null:

@Override public String execute() throws Exception
{
try
{
// get the user's submitted file from the form
MultiPartRequestWrapper wrapper = ServletActionContext.getMultiPartRequest();
File file = wrapper.getFile("avatar");
if (file != null)
{
// get Jira components
AvatarManager avatarManager = ComponentAccessor.getAvatarManager();
ProjectManager projectManager = ComponentAccessor.getProjectManager();
// get data to create a new avatar
String path = file.getPath();
// this test assumes png format
String type = AvatarManager.PNG_CONTENT_TYPE;
IconType iconType = IconType.PROJECT_ICON_TYPE;
// this test assumes at least one project exists
Project project = projectManager.getProjectObjects().iterator().next();
IconOwningObjectId id = new IconOwningObjectId(project.getId().toString());
InputStream input = new FileInputStream(file);
// this test assumes the image is larger than 10x10
Selection selection = new Selection(0,0,10,10);
// create the avatar
Avatar avatar = avatarManager.create(path,type,iconType,id,input,selection);
message = avatar.getId().toString();
}
return "test";
}
catch (Exception e)
{
// set the message field for display
message = e.getMessage();
return "error";
}
}

This could still be wrong, please be sure to let me know.

 

However, when I do this, the 'test' view is still not displayed. It still goes to the error page. The reason I have been unable to give you a more explicit error explanation, is that no error message is returned on the error page. instead, just '$message' is displayed, as if the getter method getMessage() is no longer available. Which I do not know how to explain. I know that the function works, in this scenario the getter method works fine:

@Override public String execute() throws Exception
{
try
{
message = "display?";
return "test";
}
catch (Exception e)
{
// set the message field for display
message = e.getMessage();
return "error";
}
}

 

I hope this helps clarify the issue. Again, thank you for helping.

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 17, 2017

Unfortunately, I do not have time to write the code. But the point is

execute method always works. That is why you can not add your logic there. Leave it just return "test". In this case you will be able to see your test.vm

Add to your TestRun doSave method and move all logic there.

In test.vm change  <form class="aui" action="Test.jspa?"> to <form class="aui" action="Test!save.jspa?">

In this case your execute method will just show the test.vm. And when you choose a file doSave method will be called which will save the avatar.

Kirk Walek November 17, 2017

I've changed the webwork class to this:

import com.atlassian.jira.web.action.JiraWebActionSupport;
import webwork.action.ServletActionContext;
import webwork.multipart.MultiPartRequestWrapper;

import java.io.File;

public class TestPage extends JiraWebActionSupport
{
public String doExecute() throws Exception
{
return "test";
}

public String doSave() throws Exception
{
MultiPartRequestWrapper wrapper = ServletActionContext.getMultiPartRequest();
File file = wrapper.getFile("avatar");
return "test";
}
}

test.vm to this:

<body id="jira" class="aui-layout aui-theme-default aui-page-focused">
<div id="page">
<section id="content" role="main">
<div class="aui-page-panel">
<div class="aui-page-panel-inner">
<section class="aui-page-panel-content">
<h2>Get Avatar</h2>
<form class="aui" action="Test!save.jspa?">
<div style="width: 48%; float: left">
<fieldset>
<h4>Project Avatar</h4>
<div class="field-group">
<label for="avatar-field">Project Avatar:</label>
<input class="upfile" type="file" id="avatar-field" name="avatar">
</div>
</fieldset>
<br>
</div>
<div class="buttons-container">
<div class="buttons">
<button class="aui-button aui-button-primary" style="float: right">Submit</button>
</div>
</div>
</form>
</section>
</div>
</div>
</section>
</div>
</body>

When I go to the page test.vm: it loads, I choose a file, I click submit, I then get the error. The error occurs upon trying to use the class MultiPartRequestWrapper.

 

Could you please elaborate on #1 in your first reply.

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 17, 2017

In IDEA go to file ->settings and type maven in the search field. Then you will see Maven choice. Choose it and you will be able to change maven home directory. You shoud choose the directory of your atlassian sdk maven.

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 17, 2017

Could you provide the error message of the MultipartRequestWrapper?

Kirk Walek November 20, 2017

After changing the maven home directory, The import issues went away. Sorry for having had such a simple problem take so long to resolve -_-

With the webwork class as follows:

import com.atlassian.jira.web.action.JiraWebActionSupport;
import webwork.action.ServletActionContext;
import webwork.multipart.MultiPartRequestWrapper;

public class TestPage extends JiraWebActionSupport
{
private String message;

public String doExecute() throws Exception
{
return "test";
}

public String doSave() throws Exception
{
try
{
MultiPartRequestWrapper wrapper = ServletActionContext.getMultiPartRequest();
if (wrapper == null)
{
throw new Exception("null wrapper");
}
return "test";
}
catch (Exception e)
{
message = e.getMessage();
return "error";
}
}

public String getMessage()
{
return message;
}
}

I am now getting the message "null wrapper" on the error page. I've still got some figuring out to do with the MultiPartRequestWrapper, I don't know why it's null, but my initial problem has been resolved. If I can't figure this out I'll post a new question.

 

Thanks again

Kirk Walek November 20, 2017

For anyone else that might read through this:

to finally get the MultiPartRequestWrapper to work, I just needed to adjust the <form> tag in this way -

<form class="aui" action="Test!save.jspa?" method="post" enctype="multipart/form-data">
Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 20, 2017

Thanks for the post

Suggest an answer

Log in or Sign up to answer