I have a java we application that is working with velocity. I get two variables in the first page via url that I extract using ureq.getParameter() method. One of the other classes that has a velocity container and I need to send one of the variables from the url to this velocity container. I tried creating an instance of the first class in the second class and using getVariable name method to do that but it did not work. Can someone tell me how I can do this?
Class 1:
package org.olat.dispatcher;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.olat.core.gui.UserRequest;
public class RemoteLoginformDispatcher implements Dispatcher {
private static final String PARAM_newUrl = "ret";
private static String newURL;
#Override
public void execute(
final HttpServletRequest request,
final HttpServletResponse response,
final String uriPrefix) {
UserRequest ureq = null;
try {
ureq = new UserRequest(uriPrefix, request, response);
newURL = ureq.getParameter(PARAM_newUrl);
} catch () {
}
}
public String getURL(){
return newURL;
}
}
Class 2:
public class BaseChiefController extends DefaultChiefController implements ContentableChiefController {
//Velocity container mainvc created here. It interacts with a html file. Removed the code that would not really matter
//mainvc.contextPut("newURL", "something");
//The below statement works. When I try with something, the something appears in the html file.
mainvc.contextPut("newURL", myLogin.getURL());
}
To create an instance of another class, simply create a "public CLASSNAME" method, and inside define all class variables with the "this" modfier. Then, call out the function you wish to use from that method, and when you want to use the class, just do "new CLASSNAME(args);"
Although, I am not really sure I am understanding your question.
Maybe this is your answer. You can use variables from one class to another class by making the variable static, then doing "CLASSNAME.VARIABLENAME = WHATEVER".
EDITED:
Okay, so as far as I can tell, you are using a method to return a static value from the class, which is much slower than just doing "newURL", RemoteLoginformDispatcher.newURL);.
Why not try this, as it is probably faster, and it should always work if newURL is defined. Otherwise, you have a different problem, and newURL is not being defined. If this is the case, try printing the caught Exception.
Related
I'm searching for a concept to forward an object to subobjects.
Example:
I would like to create log files for several main Objects, that include sub objects (imagine a REST server that would log every single connection by ID).
Creating one big log file is simple ( redirect System.out.println, I already encapsulated that)
Example code:
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Application.java
package com.dev4ag;
class Application{
private ElementA elA;
private String prefix;
public Application(String name){
this.elA = new ElementA();
this.prefix = name;
}
public void countUp(){
Debugger.debug(this.prefix+": I will now count up");
this.elA.doSomeStuff();
}
}
ElementA.java
package com.dev4ag;
class ElementA{
private int counter;
private SubElementA subElementA;
public void doSomeStuff(){
counter++;
Debugger.debug("Counter is: "+counter);
}
//Constructor
public ElementA(){
subElementA = new SubElementA();
this.counter = 0;
};
}
SubElementA.java
package com.dev4ag;
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Debugger.java
package com.dev4ag;
public class Debugger {
public static void debug(String output){
//Just imagine we would write to a file here ;)
System.out.println(output);
}
}
(it was more easy to write system.out.println than to create a file, just imagine, Debugger.debug would write to a file).
Now I am thinking about a solution to create one Debug output target for each App. I could definitely change debug to not being static and create a debug object within Application.
But is there any way to use this object in the sub classes without forwarding the debug object either through Constructor or setter function, which would mean to have to add an object for the debugger to each class?
What would be the most beautiful solution for that?
Note that this solution might decrease performance a lot and it is pretty dirty way, but some loggers include such data.
But you can use Thread.currentThread().getStackTrace() to get stacktrace like in error and get class and method from where your method was called.
If you are using java9+ then you should probably use StackWalker API instead, especially that it have nice filters and other useful features.
So then you could guess app by class/method names on the stack.
Using EasyMock 3.2. In order to unit test an UI, I have to mock some dependencies. One of them is Page. Base class for UI tests looks like this:
abstract class AbstractUiTest {
#Before
public function setUpUiDependencies() {
Page page = createNiceMock(Page.class);
Ui.setCurrentPage(page);
}
}
Most of the time I don't use the page explicity, it's just there not to throw NullPointerException when e.g. Ui calls getPage().setTitle("sth") etc.
However, in a few tests I want to explicity check if something has happend with the page, e.g.:
public class SomeTest extends AbstractUiTest {
#Test
public void testNotification() {
// do something with UI that should cause notification
assertNotificationHasBeenShown();
}
private void assertNotificationHasBeenShown() {
Page page = Ui.getCurrentPage(); // this is my nice mock
// HERE: verify somehow, that page.showNotification() has been called
}
}
How to implement the assertion method? I would really want to implement it without recording behavior to the page, replaying and verifying it. My problem is a bit more complicated, but you should get the point.
EDIT: I think that perhaps this is not really needed, since simply using replay and verify should check that the expected methods were actually called. But you said you want to do this without replaying and verifying. Can you explain why you have that requirement?
I think that you can use andAnswer and an IAnswer. You don't mention what the return value of page.showNotification() is. Assuming it returns a String, you could do this:
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.easymock.IAnswer;
import org.junit.Ignore;
import org.junit.Test;
public class SomeTest extends AbstractUiTest {
#Test
public void shouldCallShowNotification() {
final AtomicBoolean showNotificationCalled = new AtomicBoolean();
expect(page.showNotification()).andAnswer(new IAnswer<String>() {
#Override
public String answer() {
showNotificationCalled.set(true);
return "";
}
});
replay(page);
Ui.getCurrentPage();
verify(page);
assertTrue("showNotification not called", showNotificationCalled.get());
}
}
If showNotification returns void, I believe you would need to do this:
import static org.easymock.EasyMock.expectLastCall;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.easymock.IAnswer;
import org.junit.Ignore;
import org.junit.Test;
public class SomeTest extends AbstractUiTest {
#Test
public void shouldCallShowNotification() {
final AtomicBoolean showNotificationCalled = new AtomicBoolean();
page.showNotification();
expectLastCall().andAnswer(new IAnswer<Void>() {
#Override
public Void answer() {
showNotificationCalled.set(true);
return null;
}
});
replay(page);
Ui.getCurrentPage();
verify(page);
assertTrue("showNotification not called", showNotificationCalled.get());
}
}
Note: I've used an AtomicBoolean to record whether the method was called. You could also use a boolean array of a single element, or your own mutable object. I used AtomicBoolean not for its concurrency properties, but simply because it is a handy mutable boolean object that is already present in the Java standard libraries.
The other thing that I have done to verify that a method was being called is to not use a mock at all, but to create an instance of Page as an anonymous inner class and override the showNotification method, and record somewhere that the call occurred.
Use a nice mock in the tests where you don't care what happens to page and a normal mock in those tests where you want to test something explicit - and use expect, verify etc. I.e. have two variables in your setup method: nicePage (acts as a stub) and mockPage (acts as a mock)
I'm trying some alterations in minecraft src. I'm trying to override a method in a class so I don't have to edit the original class.
In the regular class I want to alter this method:
public void sendChatMessage(String par1Str)
{
this.sendQueue.addToSendQueue(new Packet3Chat(par1Str));
}
So in my subclass I have this code:
package cobalt.gui;
import cobalt.hacks.*;
import net.minecraft.client.Minecraft;
import net.minecraft.src.EntityClientPlayerMP;
import net.minecraft.src.NetClientHandler;
import net.minecraft.src.Session;
import net.minecraft.src.World;
public class Console extends EntityClientPlayerMP {
public Console(Minecraft par1Minecraft, World par2World,
Session par3Session, NetClientHandler par4NetClientHandler) {
super(par1Minecraft, par2World, par3Session, par4NetClientHandler);
}
#Override
public void sendChatMessage(String par1Str) {
if (par1Str.startsWith(".help")) {
//Do stuff
return;
}
}
}
From my understanding, anytime a method is called, it should be "redirected" for the subclass to handle? (Tell me if I'm wrong ha)
The if statement does work correctly if I modify the original class.
Thank you very much!
This would only work if somehow the rest of the minecraft code starts using your class, Console, where it meant to use EntityClientPlayerMP. Without that, your function will not be called.
If you want to change the behavior of the game, the easiest way would be to change EntityClientPlayerMP itself. If you want to use the modified class Console elsewhere in the code, then what you have done is fine.
It depends on the actual object type. If the object is of type Console e.g. EntityClientPlayerMP obj = new Console(..) and obj.sendChatMessage(..) it'll work. But if the object itself is of type EntityClientPlayerMP like new EntityClientPlayerMP(..) It won't work
We have a URL object in one of our Java classes that we want to mock, but it's a final class so we cannot. We do not want to go a level above, and mock the InputStream because that will still leave us with untested code (we have draconian test coverage standards).
I've tried jMockIt's reflective powers but we work on Macs and there are problems with the Java agent handler that I haven't been able to resolve.
So are there any solutions that do not involve using real URLs in the junit test?
Like Rob said, if what you want is to mock the connection returned from the URL, you can extend URLStreamHandler. For instance, with mockito:
final URLConnection mockUrlCon = mock(URLConnection.class);
ByteArrayInputStream is = new ByteArrayInputStream(
"<myList></myList>".getBytes("UTF-8"));
doReturn(is).when(mockUrlCon).getInputStream();
//make getLastModified() return first 10, then 11
when(mockUrlCon.getLastModified()).thenReturn((Long)10L, (Long)11L);
URLStreamHandler stubUrlHandler = new URLStreamHandler() {
#Override
protected URLConnection openConnection(URL u) throws IOException {
return mockUrlCon;
}
};
URL url = new URL("foo", "bar", 99, "/foobar", stubUrlHandler);
doReturn(url).when(mockClassloader).getResource("pseudo-xml-path");
When I have a class that can't be easily mocked because it is final (or sealed in C#), my usual route is to write a wrapper around the class and use the wrapper wherever I would use the actual class. Then I would mock out the wrapper class as necessary.
I went with the following:
public static URL getMockUrl(final String filename) throws IOException {
final File file = new File("testdata/" + filename);
assertTrue("Mock HTML File " + filename + " not found", file.exists());
final URLConnection mockConnection = Mockito.mock(URLConnection.class);
given(mockConnection.getInputStream()).willReturn(
new FileInputStream(file));
final URLStreamHandler handler = new URLStreamHandler() {
#Override
protected URLConnection openConnection(final URL arg0)
throws IOException {
return mockConnection;
}
};
final URL url = new URL("http://foo.bar", "foo.bar", 80, "", handler);
return url;
}
This gives me a real URL object that contains my mock data.
If you don't want to create a wrapper :
Register a URLStreamHandlerFactory
Make the method you want public
Mock the chain
abstract public class AbstractPublicStreamHandler extends URLStreamHandler {
#Override
public URLConnection openConnection(URL url) throws IOException {
return null;
}
}
public class UrlTest {
private URLStreamHandlerFactory urlStreamHandlerFactory;
#Before
public void setUp() throws Exception {
urlStreamHandlerFactory = Mockito.mock(URLStreamHandlerFactory.class);
URL.setURLStreamHandlerFactory(urlStreamHandlerFactory);
}
#Test
public void should_return_mocked_url() throws Exception {
// GIVEN
AbstractPublicStreamHandler publicStreamHandler = Mockito.mock(AbstractPublicStreamHandler.class);
Mockito.doReturn(publicStreamHandler).when(urlStreamHandlerFactory).createURLStreamHandler(Matchers.eq("http"));
URLConnection mockedConnection = Mockito.mock(URLConnection.class);
Mockito.doReturn(mockedConnection).when(publicStreamHandler).openConnection(Matchers.any(URL.class));
Mockito.doReturn(new ByteArrayInputStream("hello".getBytes("UTF-8"))).when(mockedConnection).getInputStream();
// WHEN
URLConnection connection = new URL("http://localhost/").openConnection();
// THEN
Assertions.assertThat(new MockUtil().isMock(connection)).isTrue();
Assertions.assertThat(IOUtils.toString(connection.getInputStream(), "UTF-8")).isEqualTo("hello");
}
}
PS : I don't know how to cancel the numbered list auto-spacing after last line
I think you can use Powermock to do this. I was able to mock URL class using PowerMock lately. Hope this helps.
/* Actual class */
import java.net.MalformedURLException;
import java.net.URL;
public class TestClass {
public URL getUrl()
throws MalformedURLException {
URL url = new URL("http://localhost/");
return url;
}
}
/* Test class */
import java.net.URL;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(value = { TestClass.class })
public class TestClassTest {
private TestClass testClass = new TestClass();
#Test
public void shouldReturnUrl()
throws Exception {
URL url = PowerMockito.mock(URL.class);
PowerMockito.whenNew(URL.class).withParameterTypes(String.class)
.withArguments(Mockito.anyString()).thenReturn(url);
URL url1 = testClass.getUrl();
Assert.assertNotNull(url1);
}
}
I have used a URLHandler that allows me to load a URL from the classpath. So the following
new URL("resource:///foo").openStream()
would open a file named foo from within the class path. To do this, I use a common utility library and register a handler. To use this handler, you just need to call:
com.healthmarketscience.common.util.resource.Handler.init();
and the resource URL is now available.
Create a URL-object pointing to the test class itself.
final URL url =
new URL("file://" + getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
I would look again at why you want to mock a final data object. Since by definition you aren't subclassing the object in your actual code, and it's not going to be the object under test, you shouldn't need to white-box test this code; just pass in whatever (real) URL objects are appropriate, and check the output.
Mock objects are useful when it's difficult to create a real object appropriate, or the real object's method are either time-consuming or depend on some stateful external resource (like a database). Neither of these apply in this case so I can't see why you can't just construct a real URL object representing the appropriate resource location.
JMockit does indeed allow you to mock a final JRE class like java.net.URL.
It seems the Attach API in jdkDir/lib/tools.jar available in implementations of JDK 1.6 other than Sun's does not work as well. I guess this stuff is still too new/advanced, or simply didn't get the necessary attention from the other JDK vendors (Apple, IBM with the J9 JDK, Oracle with the JRockit JDK).
So, if you run into problems by having tools.jar in the classpath, try using the "-javaagent:jmockit.jar" JVM argument. It tells the JVM to directly load the java agent at startup, without using the Attach API. That should work in the Apple JDK 1.5/1.6.
Does the URL class implement an interface? If so then you could instantiate it using inversion of control or a configurable factory, rather than by direct construction, this would allow you to inject/construct a test instance at test runtime rather than the final instance you currently have.
You can mock the constructor this way:
new MockUp<URL>() {
#Mock
public void $init(Invocation invocation, String string) {
}
};
Using PowerMockito for my case was the easiest solution. PowerMockito allows mocking static, final classes.
I'm trying to use JNA with a DLL in Windows, so far I was able to successfully call a function called c_aa_find_devices(). But all the functions start with c_aa and I would like to rename it to find_devices().
From what I gather the way to do this is with StdCallFunctionMapper but I can't find the documentation of how to use it in an example (i.e. how to map a DLL function by name or by ordinal to a desired name in the wrapped Java library interface). Any suggestions on where the docs are?
A complete working example, using a function mapper.
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.win32.StdCallFunctionMapper;
import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class JnaTest {
static {
Map options = new HashMap();
options.
put(
Library.OPTION_FUNCTION_MAPPER,
new StdCallFunctionMapper() {
HashMap<String, String> map = new HashMap() {
{
put("testMethod", "testMethod#0");
}
};
#Override
public String getFunctionName(NativeLibrary library, Method method) {
String methodName = method.getName();
return map.get(methodName);
}
}
);
File LIB_FILE = new File("test.dll");
Native.register(NativeLibrary.getInstance(LIB_FILE.getAbsolutePath(), options));
}
private static native int testMethod();
public static void main(String[] args) {
testMethod(); // call the native method in the loaded dll with the function name testMethod#0
}
}
Using StdCallMapper won't do good - it is supposed to map werid windows std lib names that have embedded total byte lenght of parameters embedded as part of the name. Since it is done to std lib only (just guessing on that, but 99% you'r functions are not the case).
If your dll uses some common prefix on all functions you need just to use something like:
class Mapper implements FunctionMapper{
public String getFunctionName(NativeLibrary library, Method method) {
return GenieConnector.FUNCTION_PREFIX + method.getName();
}
}
Where GenieConnector.FUNCTION_PREFIX is that common prefix. Bear in mind that i implement FunctionMapper, not extend StdCallMapper
From the documentation you need to provide a FunctionMapper in the original call to loadLibrary that converts the name. However you also need to keep the standard call mapping so try something like the following:
Map options = new HashMap();
options.
put(
Library.OPTION_FUNCTION_MAPPER,
new StdCallFunctionWrapper() {
public String getFunctionName(NativeLibrary library, Method method) {
if (method.getName().equals("findDevices")
method.setName("c_aa_find_devices");
// do any others
return super.getFunctionName(library, method);
}
}
);
Native.loadLibrary(..., ..., options);
All JNA documentation is located at the primary web page, the JavaDoc overview, and the JavaDocs themselves.
The example above is the right idea, in that you need to tweak the function name returned by the generic StdCallFunctionMapper (assuming you're using the stdcall calling convention). However, Method.setName() doesn't exist and you wouldn't want to call it if it did. You'll need to get the String result and replace the Java function name within it with the target native name, e.g.
name = super.getFunctionName();
name = name.replace("find_devices", "c_aa_find_devices");
More generically, you can simply tack on a "c_aa_" prefix to the returned name (or after any leading underscore), since stdcall decorations are at the end of the name.