1

Trying to build a Struts 2 app which directs the user to a page (Display.jsp) that shows the color of a user defined RGB color configuration. I get the example from the Struts 2 Tutorial by Budi Karniawan. When I manually cut and paste the source code and build the app manually as an NB Web application, it runs fine although the RGB parameters throw validation errors despite being input in the correct format (I checked that I am inputting using comma separated numbers for the RGB co-ordinates ie: green is 0,255,0). The directory structure is:

enter image description here

Then I decided to import the project file (creating a Web Application from Existing Sources option). I used the ant build.xml file to compile and run the application.

When I run the application through the app name:

http://localhost:8084/Budi7c

I get:

no Action mapped for namespace [/] 

Then I append the action name mapped in struts.xml

http://localhost:8084/Budi7c/Design1.action

I get an HTTP 404. But the above Deisgn1.action reference worked when I tried to build the project manually. Can anyone please tell me the best way to correctly import and run this application given the following files? I would rather use an ant script and NOT MAVEN (since there seems to be a lot of issues building Struts 2 using Maven). I would just like to know a way to avoid the 404 error when trying to run struts actions.

If I try building the app manually, the input validation fails (even though I'm inputting the numbers and separating them with commas). If I try to import and use Ant to ensure a correct build, I end up with a 404.

The app is as follows:

web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     version="2.5"> 

     <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>    
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>



<!-- Restrict direct access to JSPs. 
For the security constraint to work, the auth-constraint
and login-config elements must be present -->
<security-constraint>
    <web-resource-collection>
        <web-resource-name>JSPs</web-resource-name>
        <url-pattern>/jsp/*</url-pattern>
    </web-resource-collection>
    <auth-constraint/>
</security-constraint>

<login-config>
    <auth-method>BASIC</auth-method>
</login-config>
</web-app> 

struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />

<package name="app07c" extends="struts-default">
    <action name="Design1">
        <result>/jsp/Design.jsp</result>
    </action>
    <action name="Design2" class="app07c.Design">
        <result name="input">/jsp/Design.jsp</result>
        <result name="success">/jsp/Display.jsp</result>
    </action>
</package>

</struts>

Color.java:

package app07c;
import com.opensymphony.xwork2.ActionSupport;

public class Color extends ActionSupport {
private int red;
private int green;
private int blue;
public int getBlue() {
    return blue;
}
public void setBlue(int blue) {
    this.blue = blue;
}
public int getGreen() {
    return green;
}
public void setGreen(int green) {
    this.green = green;
}
public int getRed() {
    return red;
}
public void setRed(int red) {
    this.red = red;
}
public String getHexCode() {
    return (red < 16? "0" : "") 
            + Integer.toHexString(red)
            + (green < 16? "0" : "")
            + Integer.toHexString(green) 
            + (blue < 16? "0" : "")
            + Integer.toHexString(blue);
}
}

Design.java:

package app07c;
import com.opensymphony.xwork2.ActionSupport;

public class Design extends ActionSupport {
private String designName;
private Color color;
public Color getColor() {
    return color;
}
public void setColor(Color color) {
    this.color = color;
}
public String getDesignName() {
    return designName;
}
public void setDesignName(String designName) {
    this.designName = designName;
}
}

MyColorConverter.java:

package app07c.converter;
import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;
import app07c.Color;
import com.opensymphony.xwork2.conversion.TypeConversionException;

public class MyColorConverter extends StrutsTypeConverter {
public Object convertFromString(Map context, String[] values,
        Class toClass) {
    boolean ok = false;
    String rgb = values[0];
    String[] colorComponents = rgb.split(",");
    if (colorComponents != null 
            && colorComponents.length == 3) {
        String red = colorComponents[0];
        String green = colorComponents[1];
        String blue = colorComponents[2];
        int redCode = 0;
        int greenCode = 0;
        int blueCode = 0;
        try {
            redCode = Integer.parseInt(red.trim());
            greenCode = Integer.parseInt(green.trim());
            blueCode = Integer.parseInt(blue.trim());
            if (redCode >= 0 && redCode < 256 
                    && greenCode >= 0 && greenCode < 256 
                    && blueCode >= 0 && blueCode < 256) {
                Color color = new Color();
                color.setRed(redCode);
                color.setGreen(greenCode);
                color.setBlue(blueCode);
                ok = true;
                return color;
            }
        } catch (NumberFormatException e) {
        }
    }
    if (!ok) {
        throw new 
                TypeConversionException("Invalid color codes");
    }
    return null;
}

public String convertToString(Map context, Object o) {
    Color color = (Color) o;
    return color.getRed() + "," 
            + color.getGreen() + ","
            + color.getBlue();
}
}

Design.jsp:

<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Color</title>
<style type="text/css">@import url(css/main.css);</style>
<style>
.errorMessage {
color:red;
}
</style>
</head>
<body>
<div id="global" style="width:450px">
<h4>Color</h4>
Please enter the RGB components, each of which is
an integer between 0 and 255 (inclusive). Separate two components
with a comma. For example, green is 0,255,0.
<s:form action="Design2">
    <s:textfield name="designName" label="Design Name"/>
    <s:textfield name="color" label="Color"/>
    <s:submit/>     
</s:form>

</div>
</body>
</html>

Display.jsp:

<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Design Details</title>
<style type="text/css">@import url(css/main.css);</style>
<style type="text/css">
     .colorSample {
border:1px solid black;
width:100%;
height:100px;
background:#<s:property value="color.hexCode"/>;
}
</style>
</head>
<body>
<div id="global" style="width:250px">
<h4>Design details:</h4>
    Design name: <s:property value="designName"/>
    <br/>Color code: <s:property value="color"/>
    <div class="colorSample"/>
    </div>
    </body>
     </html>

I tried to change the web contents folder from /jsp to / so that project structure is the same as the directory structure. I then use the ant build script to compile and run the project and get the following stack:

ant -f C:\\struts2\\budi_ebook\\struts2extractb\\app07c -DforceRedeploy=false     -Ddirectory.deployment.supported=true -Dnb.wait.for.caches=true run
init:
 deps-module-jar:
deps-ear-jar:
deps-jar:
Warning: Program Files (x86)\F-Secure\Anti-Virus\aquarius\fa.log modified in the future.
Warning: Program Files\CommVault\Simpana\Log Files\CVD.log modified in the future.
Warning: Users\ManaarDC\NTUSER.DAT modified in the future.
Warning: Users\ManaarDC\ntuser.dat.LOG1 modified in the future.
Warning: Users\RedGuard_Admin.MANAARNET\AppData\Local\Temp\3\output1375645810208 modified in     the future.
Warning: Users\RedGuard_Admin.MANAARNET\AppData\Local\Temp\3\toolbar_log.txt modified in the     future.
Warning: Windows\Temp\avg_secure_search.log modified in the future.
Warning: app\ManaarDC\diag\rdbms\orcldw\orcldw\trace\orcldw_dbrm_3148.trc modified in the future.
Warning: app\ManaarDC\diag\rdbms\orcldw\orcldw\trace\orcldw_dbrm_3148.trm modified in the future.
Warning: app\ManaarDC\product\11.2.0\dbhome_1\D5H9RBP1.ManaarNet.com_orclDW\sysman\emd\agntstmp.txt modified in the future.
 Warning: app\ManaarDC\product\11.2.0\dbhome_1\D5H9RBP1.ManaarNet.com_orclDW\sysman\log\emagent.trc modified in the future.
Warning: app\ManaarDC\product\11.2.0\dbhome_1\D5H9RBP1.ManaarNet.com_orclDW\sysman\log\emoms.log modified in the future.
Warning: app\ManaarDC\product\11.2.0\dbhome_1\D5H9RBP1.ManaarNet.com_orclDW\sysman\log\emoms.trc modified in the future.    
Warning: app\ManaarDC\product\11.2.0\dbhome_1\oc4j\j2ee\OC4J_DBConsole_D5H9RBP1.ManaarNet.com_orclDW\log\em-application.log modified in the future.
Warning: inetpub\logs\LogFiles\W3SVC1\u_ex130804.log modified in the future.
C:\struts2\budi_ebook\struts2extractb\app07c\nbproject\build-impl.xml:841: 
java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.Arrays.copyOfRange(Arrays.java:2694)
at java.lang.String.<init>(String.java:203)
at java.lang.String.substring(String.java:1913)
at java.util.StringTokenizer.nextToken(StringTokenizer.java:352)
at org.apache.tools.ant.util.FileUtils.normalize(FileUtils.java:741)
at org.apache.tools.ant.util.FileUtils.resolveFile(FileUtils.java:616)
at org.apache.tools.ant.types.resources.FileResource.<init>(FileResource.java:60)
at org.apache.tools.ant.util.SourceFileScanner$1.<init>(SourceFileScanner.java:96)
at org.apache.tools.ant.util.SourceFileScanner.restrict(SourceFileScanner.java:95)
at org.apache.tools.ant.taskdefs.Copy.buildMap(Copy.java:787)
at org.apache.tools.ant.taskdefs.Copy.scan(Copy.java:744)
at org.apache.tools.ant.taskdefs.Copy.iterateOverBaseDirs(Copy.java:666)
at org.apache.tools.ant.taskdefs.Copy.execute(Copy.java:563)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.GeneratedMethodAccessor90.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:392)
at org.apache.tools.ant.Target.performTasks(Target.java:413)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:283)
at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:541)
at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:153)
  BUILD FAILED (total time: 12 minutes 5 seconds)
Roman C
  • 49,761
  • 33
  • 66
  • 176
jay tai
  • 419
  • 1
  • 17
  • 35
  • I always build struts2 projects in Netbeans using maven... File->New Project -> (Categories pane: choose Maven), (Project pane: choose Web Application), remainder of instructions follow: http://stackoverflow.com/questions/5718418/struts2-netbeans-7 I think I can set up a blank project in a couple minutes... downloading dependencies aside – Quaternion Aug 05 '13 at 01:35

2 Answers2

1

Can't see the web content root directory from your project explorer because it's not a directory structure, it is a project structure. For example if you use maven then it should be [project root]/src/main/webapp. This directory should contain WEB-INF folder. If you have set web content root folder to /jsp in the project settings then it's wrong because it affects JSPs and other project files. You should set it to / instead. In this case the project root and the web content root would be the same or create a new folder in the project root folder say WebContent and place jsp, WEB-INF, and other web resources there. Set the web content root project settings to /WebContent. Then you could use /jsp/ in the result mappings.

Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Ok I tried to upload as accurate an image as possible of the directory structure. Please let me know if this is ok. The problem is now it's not running. When I select the 'run' option it just freezes. IDEs are confusing me. I think I would benefit with a good book which explains how to build Struts2 using Netbeans. Using Maven I discovered has some issues with archetypes so I'm no longer sure about the best way to build Struts2 (apart from building it manually, creating war file and uploading using Tomcat manager). – jay tai Aug 04 '13 at 19:43
  • Actually when I changed the setting of web content root folder to '/' it runs but it takes a VERY long time – jay tai Aug 04 '13 at 20:00
  • The image is not readable, could you post the better image or post the text formatted as a tree. [Netbeans has a maven plugin](http://maven.apache.org/netbeans-module.html) and I don't see any difficulties to to manage a maven project from IDE with archetypes or without. – Roman C Aug 04 '13 at 20:33
  • BTW if you are building war then deploying it to the server even with tomcat manager it's very long process you are at all not using IDE deployment features and server configuration, debugging, you have lost much time, you should gain IDE skills to better manage projects. – Roman C Aug 04 '13 at 20:41
  • Hopefully the above image is clearer. On the subject of Maven, I had a hard time with the Maven plugin for Eclipse. The archetypes were producing incorrect builds. I'm trying Maven for Netbeans. I've read the Netbeans tutorials and a couple of books on Building Struts2 and using Maven in Netbeans. The guides tend to be inconsistent with a lot of examples that are missing configuration details. – jay tai Aug 04 '13 at 22:28
  • I would benefit from some functioning guides or step by step advice of how to use Maven in Netbeans to build Struts 2 applications. – jay tai Aug 04 '13 at 22:35
  • Ok I have now figured out how to build in Netbeans using Maven. I rebuilt another app which is posted here: http://stackoverflow.com/questions/18038964/struts2-required-field-validation-interceptors-not-working. Maven did not help but I will also try building the above app as soon as possible – jay tai Aug 05 '13 at 02:17
0

Well here's how I solved it. I used the Netbeans 'Web Applications with Existing Sources' to import the project. For some reason the imported project doesn't register the 'jsp' directory. It just sees the JSP files in the Web Pages directory NOT Web Pages/jsp. So i simply removed the /jsp reference in the struts.xml. The app now runs fine and the validation errors are no longer there.

I'm happy with this answer to the extent that I can run the app, but I'm not happy that I fully understand how IDEs build these type of applications as the imported directory structure is clearly wrong (and missed the jsp folder). Would be grateful if anyone could shed further light on this or if I should post a separate question on the topic of building Struts2 in Netbeans

jay tai
  • 419
  • 1
  • 17
  • 35