I have a scala case class which looks like this:
case class AddressView(id: Option[Long],
address: Address,
purpose: Seq[String])
I have to invoke this class from Java.
This does not seem to work:
AddressView billToAddress = new AddressView
(BusinessFieldValue.ShipToAddressId,
shipAddress,
(Seq<String>)Arrays.asList("BILLING"));
Can anyone tell me the right way of doing this?
So there's 2 things you need to fix; you need to wrap your Long in an Option, and you need to properly convert your List to a Scala Seq.
You addressview class takes an Option[Long] as a parameter. It would be nice if you could just pass a long to your constructor, but you must wrap your long in an Option.
Option has 2 subclasses, Some and None. So you need to import Some into your java program. You must also have the scala library added to you classpath.
For the conversion, scala provides some built in functionality in scala.collection.JavaConversions.
So the final result is..
import scala.Some;
import scala.collection.JavaConversions;
import java.util.Arrays;
public class Test {
public static void main(String[] args){
AddressView billToAddress = new AddressView
(new Some<>(BusinessFieldValue.ShipToAddressId),
shipAddress,
JavaConversions.asScalaBuffer(Arrays.asList("BILLING")));
}
}
Related
I want to provide my own implementation of JSObject as described here: https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions
JSObject is within the jdk.nashorn.api package. Unfortunately the classes of the objects you get in the api-methods are not. You get NativeArray and JO4, which are both part of the internal package. My question is, how should I handle such objects? Is it recommended to use the internal functions? Or is it possible to cast those objects to anything in the api-package?
Here is my simple example:
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.AbstractJSObject;
public class JacksonToJSObject extends AbstractJSObject {
final static ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
public static void main(String[] args) throws ScriptException, NoSuchMethodException {
String script = "var fun = function(obj) {obj.arrayField = [1,2]; obj.objField = {\"field\":\"test\"}};";
engine.eval(script);
((Invocable)engine).invokeFunction("fun", new JacksonToJSObject());
}
#Override
public void setMember(String name, Object value) {
System.out.println(value.getClass().getCanonicalName());
}
}
This is the output
jdk.nashorn.internal.objects.NativeArray
jdk.nashorn.internal.scripts.JO4
I've filed a bug against JDK https://bugs.openjdk.java.net/browse/JDK-8137258 to automatically handle the wrapping. In the meanwhile, please use the workaround suggested by Attila Szegedi.
I think we should wrap these automatically for you. In the meantime, you can pass these internal objects to jdk.nashorn.api.scripting.ScriptUtils.wrap(Object) yourself to get back a JSObject. This method is idempotent if you pass it something that's already wrapped, so this solution won't break if we fix the wrapping.
I'm creating a small java service that returns a list of restaurants depending on the selected place.
Data is retrieved from Riak using com.basho.riak:riak-client:2.0.0 and the read operation is wrapped in a TenacityCommand.
Important classes are described below and I would be happy if you could assist me in creating a solid and simple unit test.
Commands are created using a factory:
package service.command.factory;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.Namespace;
import domain.Place;
import service.command.FetchRestaurantsCommand;
public class FetchRestaurantsCommandFactory {
private final RiakClient riakClient;
private final Namespace namespace;
public FetchRestaurantsCommandFactory(final RiakClient riakClient, final Namespace namespace) {
this.riakClient = riakClient;
this.namespace = namespace;
}
public FetchRestaurantsCommand create(final Place place) {
Location location = new Location(namespace, place.getName());
FetchValue riakCommand = new FetchValue.Builder(location).build();
return new FetchRestaurantsCommand(riakClient, riakCommand);
}
}
And the command looks like this:
package service.command;
import java.util.Optional;
import service.command.keys.WhereToEatDependencyKeys;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.api.commands.kv.FetchValue.Response;
import com.yammer.tenacity.core.TenacityCommand;
import domain.Restaurant;
import domain.RestaurantList;
public class FetchRestaurantsCommand extends TenacityCommand<Optional<RestaurantList>>{
private final RiakClient riakClient;
private final FetchValue fetchValue;
public FetchRestaurantsCommand(RiakClient riakClient, FetchValue fetchValue) {
super(WhereToEatDependencyKeys.RIAK_GET_RESTAURANTS);
this.fetchValue = fetchValue;
this.riakClient = riakClient;
}
#Override
protected Optional<RestaurantList> run() throws Exception {
Response response = riakClient.execute(fetchValue);
return Optional.ofNullable(response.getValue(RestaurantList.class));
}
#Override
protected Optional<RestaurantList> getFallback() {
return Optional.of(RestaurantList.createFallback(new Restaurant("My failure suggestion")));
}
}
The above classes are used like:
Place place = // Created from url parameter
RiakClient riakClient = // created on start using the app's conf
Namespace namespace = // created on start using the app's conf
FetchRestaurantsCommandFactory factory = new FetchRestaurantsCommandFactory(riakClient, namespace);
FetchRestaurantsCommand command = factory.create(place);
return command.execute();
Apart from the features provided by TenacityCommand, how should I assert that my system fetches data as expeceted?
My initial idea was to mock a RiakClient to return a predefined FetchValue.Response and then make assertions on the resulting RestaurantList.
Unfortunately its not possible to instantiate or Mockito.mock a FetchValue.Response due to its design.
The accepted answer in How to mock riak java client? describes why Mockito won't work.
As far a I understood you want to write unit test. So you want to test that assuming some Response whether Optional<RestaurantList> instance is constructed correctly or not.
What I can think of is to wrap riakClient.execute(fetchValue); in a protected (or package private) helper function like:
Response fetch() {
return riakClient.execute(fetchValue);
}
Then in your test you can inherit from FetchRestaurantsCommand and override fetch function by returning any Response
Now, you can write any test to see whether the conversion of given Response to Optional<RestaurantList> behaves as expected or not.
If you need entire code and my explanation is not clear enough let me know to provide it.
I ended up using PowerMock as suggested by #gontard. See my unit test on GitHub: FetchRestaurantsCommandTest.java
I considered to create a fake/mock RiakClient in the com.basho.riak.client package. Such class could hopefully instantiate the Response object in the same way as the real client does. It would probably work for fetchValue but it would grow too big when involving more advanced Riak concepts s.a. siblings.
I have a recurring problem using Eclipse. Consider the following example:
As you can see I've pressed Ctrl+Shift+O. I can choose from a deprecated and a non-deprecated annotation. My problem is that I am often supplied with dozens of classes and half of them are deprecated (a perfect example is the JUnit Assert classes).
My question is how can I make Eclipse ignore all deprecated classes when organizing imports?
Currently Eclipse does not provide such an option... Eclipse Documentation for Organise Imports (Kepler version).
However, with a fudge you can achieve the same result...
Eclipse allows you to provide a list of classes/packages to filter-out.
To do this, navigate to Preferences > Type Filters.
I've done this in my environment to ensure "java.awt.List" is not suggested when I really want "java.util.List".
What you want is to add all deprecated classes to this list.
This list is maintained in your eclipse workspace preferences...
File ... C:\Users\[YOUR_USER_NAME]\workspace\.metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.jdt.ui.prefs
Property ... org.eclipse.jdt.ui.typefilter.enabled=java.awt.List;
All that is required is that you create a list of deprecated classes, and store it in this properties file.
Eclispe can help create this list...
Perform a "Java Search" for "Deprecated".
Then group the results by type.
And copy the results using "Copy Qualified Name"
The results will contain Generics, and this should be removed.
For example, "javafx.scene.control.Cell<T>" should read "javafx.scene.control.Cell".
In addition to containing deprecated classes, the results will also contain any class that has the word "Deprecated". This could be a comment or a method annotation. This list will need to be filtered to retain only deprecated classes.
The script below processes this class list to remove generics, and filtering out classes that are not deprecated (ie, only has method deprecation). The class list is read from a file named "DeprecatedClassList.txt". When it cannot check the class annotation, it skips the class and prints it out (for manual checking).
import java.lang.annotation.Annotation;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ConfigurationGenerator {
public static void main(String[] args) throws Exception {
List<String> cleanedList = Files
.readAllLines(Paths.get("DeprecatedClassList.txt")).stream()
.map(ConfigurationGenerator::removeGenerics)
.filter(ConfigurationGenerator::hasDeprecatedConstructor)
.collect(Collectors.toList());
String propertyName = "org.eclipse.jdt.ui.typefilter.enabled=";
String propertyValue = String.join(";", cleanedList).concat(";");
String configuration = propertyName + propertyValue;
System.out.println("Configuration property...");
System.out.println(configuration);
}
public static String removeGenerics(String className) {
int openingBracket = className.indexOf("<");
if (openingBracket == -1)
return className;
else
return className.substring(0, openingBracket);
}
public static boolean hasDeprecatedConstructor(String className) {
Class theClass = null;
try {
theClass = Class.forName(className);
} catch (Throwable e) {
// Ignore bad results
System.out.println("Skipping: " + className);
return false;
}
Annotation[] annotations = theClass.getAnnotations();
Optional<Annotation> deprecatedConstructor = Stream
.of(annotations)
.filter(annotation -> annotation.toString().equals(
"#java.lang.Deprecated()")).findAny();
return deprecatedConstructor.isPresent();
}
}
There is one problem with this approach though. You may want to use a deprecated class when a non-deprecated version does not exist. You will not see the deprecated class if it has been purposefully hidden. To resolve that, just be sure you exclude them from the filter.
I'm currently doing my first Java project and like to fully TDD it. I'm using JUnit for writing the tests. Apparently JUnit does not provide support for data providers, which makes it rather annoying to test the same method with 20 different versions of an argument. What is the most popular/standard testing tool for Java that does support data providers? I came across TestNG, but have no idea how popular that one is, or how it compares to alternatives.
If there is a way to get this behaviour is a nice way using JUnit, then that might also work.
Coworkers of mine at our company wrote a freely available DataProvider in TestNG style for JUnit which you can find on github (https://github.com/TNG/junit-dataprovider).
We use it in very large projects and it works just fine for us. It has some advantages over JUnit's Parameterized as it will reduce the overhead of separate classes and you can execute single tests as well.
An example looks something like this
#DataProvider
public static Object[][] provideStringAndExpectedLength() {
return new Object[][] {
{ "Hello World", 11 },
{ "Foo", 3 }
};
}
#Test
#UseDataProvider( "provideStringAndExpectedLength" )
public void testCalculateLength( String input, int expectedLength ) {
assertThat( calculateLength( input ) ).isEqualTo( expectedLength );
}
Edit: Since v1.7, it also supports other ways to provide data (strings, lists) and can inline the provider so that a separate method is not necessarily needed.
A full, working example can be found on the manual page on github. It also has a few more features, like collecting the providers in utility classes and accessing them from other classes etc. The manual page is very detailed, I'm sure you'll find any questions answered there.
JUnit 4 has parameterized test which is the does the same thing as php data providers
#RunWith(Parameterized.class)
public class MyTest{
#Parameters
public static Collection<Object[]> data() {
/*create and return a Collection
of Objects arrays here.
Each element in each array is
a parameter to your constructor.
*/
}
private int a,b,c;
public MyTest(int a, int b, int c) {
this.a= a;
this.b = b;
this.c = c;
}
#Test
public void test() {
//do your test with a,b
}
#Test
public void testC(){
//you can have multiple tests
//which all will run
//...test c
}
}
Depending on your needs in flexibility vs readability, you can choose Parameterized - junit's built in option, described by dkatzel. Other options are external junit runners provided by external libraries like zohhak, which let's you do:
#TestWith({
"clerk, 45'000 USD, GOLD",
"supervisor, 60'000 GBP, PLATINUM"
})
public void canAcceptDebit(Employee employee, Money money, ClientType clientType) {
assertTrue( employee.canAcceptDebit(money, clientType) );
}
or junitParams with a bit different functionality. just pick whatever suits you the most
You can use JUnit 5's ParameterizedTest. Here's an example from https://www.petrikainulainen.net/programming/testing/junit-5-tutorial-writing-parameterized-tests/ :
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
#DisplayName("Should pass the method parameters provided by the sumProvider() method")
class MethodSourceExampleTest {
#DisplayName("Should calculate the correct sum")
#ParameterizedTest(name = "{index} => a={0}, b={1}, sum={2}")
#MethodSource("sumProvider")
void sum(int a, int b, int sum) {
assertEquals(sum, a + b);
}
private static Stream<Arguments> sumProvider() {
return Stream.of(
Arguments.of(1, 1, 2),
Arguments.of(2, 3, 5)
);
}
}
It's possible to load test parameters from an annotation, a method or even a CSV file.
Here is another option. You don't have to use Google Guava, that is just my implementation.
This uses the same #Parameters as #dkatzel's answer, but instead of the class taking the arguments, the #Parameters annotation goes on specific test methods, so you can pick and choose which methods use that set of arguments.
import java.util.Collection;
import com.google.common.collect.ImmutableList;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(JUnitParamsRunner.class)
public class FrobTester {
#SuppressWarnings("unused")
private Collection validfrobAndGorpValues() {
return ImmutableList.of(
new Object[] {"frob28953", 28953},
new Object[] {"oldfrob-189-255", 1890255}
);
}
#Test
#Parameters(method = "validfrobAndGorpValues")
public void whenGivenFrobString_thenGorpIsCorrect(
String frobString,
int expectedGorpValue
) {
// Arrange
Frob frob = new Frob(frobString);
// Act
var actualGorpValue = frob.getGorpValue();
// Assert
Assert.assertEquals(actualGorpValue, expectedGorpValue);
}
}
Pack.java imports pack.TestPack; but it cannot access it. I cannot understand why it cannot access the class despite the import.
Error
Pack.java:7: TestPack() is not public in pack.TestPack; cannot be accessed from outside package
System.out.println(new TestPack().getHello());
^
1 error
Pack.java
import pack.TestPack;
import java.io.*;
public class Pack
{
public static void main(String[] args){
System.out.println(new TestPack().getHello());
}
}
TestPack.java
package pack;
import java.util.*;
import java.io.*;
public class TestPack
{
private String hello="if you see me, you ar inside class TestPack";
public String getHello(){return hello;}
TestPack(){}
}
You should make TestPack's constructor public.
public class TestPack
{
private String hello="if you see me, you ar inside class TestPack";
public String getHello(){return hello;}
public TestPack(){}
}
The thing is, even though TestPack visibility is public, its parameterless constructor visibility is package (which is the visibility when you don't specify one explicitly).
package visibility means that classes in the same package will be able to see it. Since TestPack and Pack are not in the same package, Pack can't call TestPack's constructor.
In the way you are using getHello function, you may start thinking using static methods
public class TestPack
{
private static String hello="if you see me, you ar inside class TestPack";
public static String getHello(){return hello;}
private TestPack(){}
}
then you just will do:
public class Pack
{
public static void main(String[] args){
System.out.println(TestPack.getHello());
}
}
I suggest that you don't make the class public but make the constructor public and have folks use a public interface that your class implements. It is a good idea to start the API to your package to be public interfaces (and perhaps some public abstract classes) and hide your implementation classes by not marking them as public so that you can change these over time. You can then provide a public factory methods in your package which instantiate your package private class and return them as the interface types. Here is an interface which is public:
package stackoverflow;
public interface Widget {
public void doWidgetWork(String work);
}
Here is the implementation which is "package private". The compiler wont let code outside of the same package import nor use this class at all:
package stackoverflow;
/*package*/ class WidgetHidden implements Widget {
public WidgetHidden(String configOptionA, String configOptionB){
// ...
}
public WidgetHidden(){
// ...
}
public void doWidgetWork(String work)[
// ...
}
}
notice there that the second occurrence of the word /package/ is a comment (it is not legal in java to use that word there) but many programmers use such a comment in that position to show people that it was not an accident that the class is not public; it signifies that the developer really intended that the class is deliberately "package private". To let people instantiate the class from outside of your package you provide a static factory class (else an instance factory class):
package stackoverflow;
public class WidgetFactory {
public static Widget newInstance( String configOptionA, String configOptionB) {
return new Widget( String configOptionA, String configOptionB);
}
}
The whole point of the factory class is that it hides your internal classes (the ones you hide as package private). Over time you can change your factory classes to return new classes or rename or delete the WidgetHidden class.
Many frameworks indicate which classes other developers should not use by putting them into a package with the name "internal" in it. The public interfaces would be in the main package (e.g. "com.stackoverflow.widget") and the hidden classes into your internal package which only exposes public factory classes (e.g. "com.stackoverflow.widget.internal").
A variation on the theme is to not use a static method on the factory class; make it a regular method. The alternatives are called "static factories" or "instance factories" depending on whether the method is static or not. Not making the method static seems like more work for people using your package as they first have to instantiate your factory object before using it to create Widget. Where is helpful is when people might want to set some defaults for all widgets on the constructor of the factory then use the none static newInstance methods to specify anything beyond the defaults:
public class WidgetInstanceFactory {
private String defaultOptionA = null;
public WidgetInstanceFactory( String defaultOptionA ) {
this.defaultOptionA = defaultOptionA;
}
public Widget newInstance( String optionB ) {
return new WidgetHidden( this.defaultOptionA, optionB );
}
}
It is possible to get around package private protection using reflection to find and invoke the constructor. A really nice feature of the Spring framework it that it will instantiate classes that are not public even when there is no factory class (although it is more polite to provide factory classes which Spring is happy to use also). The following code will work:
package stackoverflow.other;
class TestInstantiate {
private Widget myWidget = null;
public TestInstantiate(){
this.myWidget = instantiatePackagePrivateClass("stackoverflow.WidgetHidden");
}
private Widget instantiatePackagePrivateClass(String className)
throws ClassNotFoundException, NoSuchMethodException,
InstantiationException, IllegalAccessException,
InvocationTargetException {
#SuppressWarnings("unchecked")
Class<FileUploadSequence> clazz = (Class<Widget>) Class.forName(className);
Constructor<Widget> constructor = clazz.getConstructor(new Class[]{});
constructor.setAccessible(true);
Widget widget = (Widget) constructor.newInstance((Object[])null);
return widget;
}
}
In that example I used the no arguments constructor but clearly you can find and invoke the two string constructor using the same approach. Clearly such code gets around the intention of the programmer who wrote WidgetHidden; they wanted to hide it as they are likely to change it. Anyone who uses such a back door to manipulate the package private object should be aware that the class WidgetHidden is not part of the public API of the framework they are using so it likely to be deleted or changed without prior notice by the developer who wrote the package you are using. Renaming it to be WidgetInternal and putting it into an "internal" package make it every more the case you are telling people "do not uses". The JVM has optional security setting which prevent people from doing such tricks; but the person running the JVM has to configure it externally to dis-allow such tricks which is only useful when you want to run someone else code you don't trust and prevent it from pulling such tricks.
The book Effective Java by Josha Block 2nd Edition has a lot of discussion and examples and details of the pitfalls when trying to write a good API. It has a lot of detail to explain why you should always look to hide as many classes as you can with lots of other good "tricks of the trade".