I have a weird problem. I created a test class by extending StrutsTestCase.
public class MyActionTest extends StrutsTestCase{
public void helloTest()
{
}
}
The struts documentation says request of MockHttpServletRequest will be available by extending StrutsTestCase. Fair enough, it's a protected variable in StrutsTestCase so we should have access to it once we extend the class.
But for some reason, NO protected attribute or method of StrutsTestCase is visible in my MyActionTest.
I don't know if I am missing something, but everything seems straight forward, but yet doesn't work.
Any idea as to why the protected methods of super class are not accessible in subclass ? Should I use some specific package or something ?
List of jars I use for this task :
spring-2.5.3.jar
spring-mock-1.2.6.jar
struts2-core-2.0.11.jar
xwork-core-2.3.1.jar
Am I missing something ?
Perhaps struts2-junit-plugin http://struts.apache.org/2.x/docs/junit-plugin.html or struts2-testng-plugin http://struts.apache.org/2.x/docs/testng-plugin.html
StrutsTestCase is part of the struts2-junit-plugin. See http://struts.apache.org/2.2.3/struts2-plugins/struts2-junit-plugin/apidocs/org/apache/struts2/StrutsTestCase.html - you'll find the protected request variable there.
Just add that plugin to your classpath and you should be able to use it. Also, don't forget to use the same versions for your struts-core and the plugin.
Related
Now I'm trying to implement custom rule usin SonarQube for the next case. For example I have next class:
public class SuperClass{
#CannotOverrideAnnotation
protected void methodCanNotBeOverrided(){}
protected void methodCanBeOverrided(){}
}
And I'd like to detect cases where somebody tries to override methodCanNotBeOverrided.
public class ChildClass extend SuperClass{
protected void methodCanNotBeOverrided(){} // Noncompliant
protected void methodCanBeOverrided(){} //Compliant
}
Firstable, I think I have to visit every MethodTree and get owner of it like as:
#Override
protected void visitNode(MethodTree method){
Tree declaration = method.symbol().owner().declaration();
if (declaration.is(Tree.Kind.CLASS)) {
TypeTree superClass = ((ClassTree) declaration).superClass();
}
}
Ok, I've got superClass and I can extract fullyQualifiedName and use Reflection API.... but maybe there is other way to do it via SonarQube API?
I've found out that RetentionPolicy for this annotations equals to SOURCE, it means that I have no idea now how to implement rule, Reflection API cannot help me... Could anybody help me with ideas about this stuff.
Also I've found out that there is a very useful method in JavaSymbol.MethodJavaSymbol such as overriddenSymbol but this class doesn't belong org.sonar.plugins.java.api package and according to link I cannot use it.
org.sonar.plugins.java.api package containts the similar interface Symbol, but there is only common methods for all languages and there're not specific methods for Java.
I will be great for any help.
P.s. I'd like to emphasize that SuperClass - is an external library. I don't have an opportunity to change something there.
I am using Struts 2 to create a web application. I am using StrutsTestCase for Junit test case to test the Action class. I have imported struts2-junit-plugin-2.3.4.jar as I am using struts2-core-2.3.4.jar. Inside the testcase method, when i tried to set the request parameters, request variable is not available for use. it is showing compilation error. I am getting 'request cannot be resolve' error. In my test class i am extending StrutsTestCase which has request as protected parameter. But it is not available inside extended method.
My test action looks like this:
import org.apache.struts2.StrutsTestCase;
public class WallPlanningActionTest extends StrutsTestCase {
public void testList() {
request.setParameter("salesOrg",1);
}
You can only get compilation errors if StrutsTestCase which your class is extended is not org.apache.struts2.StrutsTestCase. You could optimize the imports or just use FQCN.
public class WallPlanningActionTest extends org.apache.struts2.StrutsTestCase {
For future readers:
I had the same problem - the protected request field was not accessible. The problem was that i hadn't add the spring libraries. StrutsTestCase uses spring-core-x.y.z and spring-test-x.y.z. It is depended on them an i couldn't find a way to use the unit tests without them.
Other dependencies could be found by opening the struts-junit-plugin jar (as archive). Open the META-INF folder and in there you will find DEPENDENCIES file with a list of all dependencies.
Hope this helps someone.
I tried to cast Action response like this:
private void mappingMethod(ActionResponse response) {
ActionResponseImpl actionResponseImpl = (ActionResponseImpl)response;
...}
In debugging on "Expression Evaluation" window I can see the type of "responce" is ActionResponseImpl, and cast does not cause exception. But on runtime I have this exeption:
java.lang.ClassCastException: com.liferay.portlet.ActionResponseImpl cannot be cast to com.liferay.portlet.ActionResponseImpl
Please tell me what is the problem.
P.S.: In PortalImpl class, the copyRequestParameters method has same string, but here it's working....
It would do you good if you refrained from using classes from portal-impl.jar in your custom plugin portlet.
ActionResponseImpl is a class in the portal-impl.jar. So if you can give a use-case as to why you are planning to use this class, then we can suggest alternative.
You have ActionResponseImpl twice on the classpath - what jars from Liferay did you include in your project? As Prakash mentions, it's portal-impl.jar, which you can not have in a plugin.
What the ClassCastException wants to tell you is that your class extends one implementation of ActionResponseImpl, but the runtime environments expects it to be another implementation - they might be identical, but as they are loaded from two different sources, the classloader cannot refer one to another superclass than it extends.
I saw this issue, when I call a method using Ajax from XHTML page. I modified my method to return simple string and removed the code that tries to modify the actionResponseImpl and that resolved the issue.
This type of errors are produced by different classloaders. A class is identified by their fully qualified class name AND its Classloader. So if you embedd portal-impl in your portlet; the action is going to receive an ActionResponseImpl instance from the portal classloader and is trying to cast this one to a class of your portlet class loader .
see more: http://www.javaspecialists.eu/archive/Issue018.html
I have a JAR file that I'm using and I want to modify one of the files inside it. In a nutshell I have
public class ClassB {
public void printMethod(){
ClassA A = new ClassA();
A.printout();
}
}
public class ClassA {
public void printout(){
System.out.println("1234");
}
}
and I want to change ClassA's printout method to
public class ClassA {
public void printout(){
System.out.println("abcd");
}
}
I know you cannot modify a JAR without unpacking/rebuilding it and for this, let's say I can't do that. Is there a way to make modifications to ClassA without actually touching the current ClassA? My approach is to have a new class inherit from ClassA with an overridden method and then have a new class inherit from ClassB that calls the Inherited ClassA
public class InheritedClassA extends ClassA{
#Override
public void printout(){
System.out.println("abcd");
}
}
public class InheritedClassB extends ClassB{
#Override
public void printMethod(){
InheritedClassA A = new InheritedClassA();
A.printout();
}
}
I don't like this approach though because in my actual JAR, so many classes are using ClassA that its a nightmare trying to correctly do this with all of them, which then all require the same process on them. I know you cannot overload/overwrite a whole class which is basically what I want to do. Is there another way to do this?
EDIT
To make it even harder, I cannot download any new frameworks or software or anything.
I can only provide pointers as I never felt the need for it.
What you are referring to is called "Bytecode enhancement", and yes there are several frameworks to achieve it.
BCEL - http://commons.apache.org/bcel/
ASM - http://asm.ow2.org/
Usually, java developers prefer to use the inversion of control pattern. This allows the code to configure itself at runtime via a configuration file - See Spring IoC for more details.
One option which may not be feasible would be to create a new version of ClassA, package it up in its own jar file, and put that ahead of the original version in your classpath.
However, this is a pretty odd scenario - why can you not update the existing jar file? Even if that means a bit of extra work, it's likely to be much cleaner in the long run than any other approach.
Guys, can anyone explain the following scenario:
1) Web application has module1.jar in its lib directory. There is a class A in that module:
package module1;
import module2.B;
public interface IA {
void methodOk() {}
void methodWithB(B param) {}
}
package module1;
import module2.B;
public class A implements IA {
public A() {}
//...
void methodWithB(B param) {
//do job on B
}
}
2) module2.jar is absent - it is not in the classpath.
3) Application is able to create objects of class A though it's missing the dependency. In application a method A.methodOk() is called.
Would be cool if you could give a reference to any spec on this.
Thanks a lot.
Since the code is already compiled, it will not throw an error until you directly use class B. From the looks of your code, you don't actually use an instance of B for anything.
If B is not used by A anywhere, then the resulting bytecode will have no reference to module2.B, therefore it gets compiled away. No dependency exists, except at compilation in this case.
If the question is unclear and B is used in A somewhere, then I'd be interested in seeing more code to try to determine what's going on.
Look at it from the perspective of the classloader. If you never have to load the class, you don't care if the bytecode for that class is missing.
Your question is really, "What triggers classloading?"
Two reasons I can think of off the top of my head are:
- Construction
- Static access