Parsing scalaz.Validation in Java - java

I have a scala function with the following signature:
def getValue: Validation[ Throwable, String ]
Now, I want to process in Java the result (say res) of calling this function.
I can call res.isSuccess() and res.isFailure() but how do I extract the underlying Throwable or success String ?
I tried casting but testing (res instanceof scalaz.Failure) results in a scalaz.Failure cannot be resolved to a type (the scala and scalaz jars are visible)
Is there a generic way of doing this for Validation, Option, Either, etc... ?
EDIT I realize I can probably use a fold but that would lead to a lot of ugly boilerplate code in Java (which does not need more). Anything better looking ?

Success and Failure are both case classes:
final case class Success[E, A](a: A) extends Validation[E, A]
final case class Failure[E, A](e: E) extends Validation[E, A]
So you can write the following, for example:
import scalaz.*;
public class Javaz {
public static void main(String[] args) {
Validation<Throwable, String> res = new Success<Throwable, String>("test");
if (res.isSuccess()) {
System.out.println(((Success) res).a());
} else {
System.out.println(((Failure) res).e());
}
}
}
For Option and Either you can use the get method (after taking the left or right projection in the case of Either).
If at all possible it's probably cleaner to do this kind of unwrapping with a fold, etc. on the Scala side, though.

Related

How to automatically print all parameter values of Java function at runtime

I want to print automatically all the parameter values of my functions at runtime.
Just imagin that I have the following two methods:
public void doAction(String firstParam, String SecondParam) {
Util.printAllParameter(this);
}
public void doAction(String firstParam) {
Util.printAllParameter(this);
}
If I call to this functions:
doAction("a", "b"); --> Desired result: Print "a, b"
doAction("a"); --> Desired result: Print "a"
I don't want something like this (This is not reusable, it is static):
System.out.println(firstParam + "," + SecondParam);
I need a reusable method that I can use in different functions with different number of parameter. I want to call a function like "Util.printAllParameter()" and then print all the parameters.
Thanks in advance.
To do it generally would require rewriting the bytecode (probably with a Java Agent, or library using it) or the source code.
The way do it without hacking the code is to use an interface and a Proxy. Interfaces are often suggested, but Java gets in the way with its old fashioned, super verbose syntax.
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.stream.*;
// Gratuitous use of new fangled record feature and streams.
record TraceInvocation(PrintStream out) {
public <T> T trace(Class<T> type, T target) {
Objects.requireNonNull(target);
return type.cast(Proxy.newProxyInstance(
type.getClassLoader(),
new Class<?>[] { type },
(proxy, method, args) -> {
// Apparently args can be null. Ffs.
out.println(
(target==null ? type.getSimpleName() : escape(target))+
"."+method.getName()+
// There's probably a better way without {}.
"("+(args==null ? "" : String.join(", ",
Stream.of(args)
.map(TraceInvocation::escape)
.toArray(String[]::new)
))+")"
);
return method.invoke(target, args);
}
));
}
// Don't even think about allowing log injection.
// (Okay, weird syntax.)
private static String escape(Object object) {
// I am not a fan of streams.
int[] escaped = String.valueOf(object).codePoints().flatMap(cp ->
(cp == '\\' || cp == '.' || cp == ',') ?
IntStream.of('\\', cp) :
(' ' <= cp && cp <= '~' ) ?
IntStream.of(cp) :
("\\"+/*(int)*/cp+"\\").codePoints()
).toArray();
return new String(escaped, 0, escaped.length);
}
}
Use as:
CharSequence cs = new TraceInvocation(System.err)
.trace(CharSequence.class, "Scunthorpe");
cs.subSequence(4, 10).length(); // No log for length
cs.charAt(2);
cs.length();
Possible variation include filtering which methods to display, logging return values/exceptions, alternative to toString and tracing returned values.
I found this approach really useful when dealing with sending and receiving a stream in a proprietary format.
You can write a simple utility method that like:
public void trace(String methodName, Object... args) {
that then inspects all the arguments and prints a nice string for you.
But you have that explicit passing of the method name as string, which can't be avoided. Yes, theoretically, one call create a stack trace by throwing/catching an exception, and deduce the method name, but that is a real performance killer, which you absolutely can't do for ordinary tracing that is supposed to happen millions of time per day.
So: there are no "built-in" mechanisms in the Java language to get you there. No "macros" or some sort of "templating" to just "pull" such behavior into your production code without doing it explicitly.
But there is the concept of "Aspect Oriented Programming". Meaning: you have another tool that modifies your production code, for example to automatically add such trace statements, as a part of the build/compile process.
Certain technology stacks, for example spring might come with such technology.
If you are not using such frameworks, you would have to "add" something like that to your setup.

Java optional: map to subclass or else super class

I am trying to re-write a scala example of a POC project from Manning's "Akka in Action" in Java. The project is a small Http server for creating events and buying tickets.
I am at a point when an actor can send an Optional<Event> to my RestApi. Depending on whether the value is present I should complete the call with OK, else NOT_FOUND.
In Scala the snippet looks as follow:
get {
// GET /events/:event
onSuccess(getEvent(event)) {
_.fold(complete(NotFound))(e => complete(OK, e))
}
}
...where getEvent returns an Option[Event] (equivalent of java's Optional<Event>). This is how I rewrote it in Java:
get(() -> onSuccess(() -> getEvent(event), eventGetRoute()))
...
//and eventGetRoute() is a function:
private Function<Optional<Event>, Route> eventGetRoute() {
return maybeEvent -> maybeEvent.map(event -> complete(OK, event, Jackson.marshaller())).orElseGet(() -> complete(NOT_FOUND));
}
This doesn't compile: Bad return type in lambda expression: Route cannot be converted to RouteAdapter. The longer (and first) complete returns a RouteAdapter and the second one returns a Route. If I re-write the above function like this:
private Function<Optional<Event>, Route> eventGetRoute() {
return maybeEvent -> {
if(maybeEvent.isPresent()) {
return complete(OK, maybeEvent.get(), Jackson.marshaller());
}
return complete(NOT_FOUND);
};
}
...then the compiler doesn't complain, but then it is not right way to map an Optional.
Java doesn't have fold method for Optional (not in SE8 at least), which allows passing the fallback-to value first.
I'm curious whether it is possible to write this function in respecting functional style.
Update:
As asked in the comments, these are the signatures of the complete methods from akka-http javadsl library:
def complete(status: StatusCode): Route = RouteAdapter(
D.complete(status.asScala))
and
def complete[T](status: StatusCode, value: T, marshaller: Marshaller[T, RequestEntity]) = RouteAdapter {
D.complete(ToResponseMarshallable(value)(fromToEntityMarshaller(status.asScala)(marshaller)))
}
What is return type of complete(OK, maybeEvent.get(), Jackson.marshaller())?
I assume RouteAdapter. If so cast it to Route so chain will be binded to Route not RouteAdaper and at the end will not have troubles with casting from super class to subclass.

Dynamically generate a single function (without subfunctions), representing a binary expression tree, at run time with Byte Buddy

Introduction
I want to compare some libraries for generating code at run time. At the moment I touched the surface of Javassist and Byte Buddy.
As a proof of concept I am trying to solve a small problem, which is a starting point for a more complex one.
Basically I have a binary expression tree which I want to convert into a single line of code and load it into my java run time. For simplicity reasons I have only add nodes and constants as leafs so far.
Javassist Reference
I already have a way for doing this in Javassist (which at least works for a single node with two leafs). The code is looking like this:
public class JavassistNodeFactory{
public DynamicNode generateDynamicNode(INode root){
DynamicNode dynamicNode = null;
try {
CtClass cc = createClass();
interceptMethod(root, cc);
compileClass(cc);
dynamicNode = instantiate(cc);
}catch (Exception e){
System.out.println("Error compiling class with javassist: "+ e.getMessage());
e.printStackTrace();
}
return dynamicNode;
}
private DynamicNode instantiate(CtClass cc) throws CannotCompileException, IllegalAccessException, InstantiationException {
Class<?> clazz = cc.toClass();
return (DynamicNode) clazz.newInstance();
}
private void compileClass(CtClass cc) throws NotFoundException, IOException, CannotCompileException {
cc.writeFile();
}
private void interceptMethod(INode root, CtClass cc) throws NotFoundException, CannotCompileException {
CtMethod calculateMethod = cc.getSuperclass().getDeclaredMethod("calculateValue",null);
calculateMethod.setBody("return "+ nodeToString(root)+ ";");
}
private CtClass createClass() throws CannotCompileException, NotFoundException {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(
"DN"+ UUID.randomUUID().toString().replace("-","")
);
cc.setSuperclass(pool.get("org.jamesii.mlrules.util.runtimeCompiling.DynamicNode"));
return cc;
}
private static String nodeToString(INode node){
if (node.getName().equals("")){
return ((ValueNode)node).getValue().toString();
}else{
List<? extends INode> children = node.getChildren();
assert(children.size()==2);
return ("("+nodeToString(children.get(0))+node.getName()+nodeToString(children.get(1))+")");
}
}
}
The DynamicNode class looks like this:
public class DynamicNode implements INode {
#Override
public <N extends INode> N calc() {
Double value = calculateValue();
return (N) new ValueNode<Double>(value);
}
#Override
public List<? extends INode> getChildren() {
return null;
}
#Override
public String getName() {
return null;
}
private Double calculateValue() {
return null;
}
}
The important part is the nodeToString() function, where I generate an arithmetic formula represented by the returned string, from a given root node. TheValueNode is a leaf of the tree with a constant Value, which would be returned as a String.
Other nodes (only add nodes for my case) will call the function recursively for each child and print brackets arround the expression as well as printing the operator (returned by the getName() function) in the middle of the two children (in short: "(leftChild+rightChild)").
The body of the calculateValue() function will be altered in the interceptMethod() function by Javassist, to return the result of the generated formula.
Byte Buddy Attempt
I have played around with Byte Buddy to achieve a similar solution. But as I looked deeper into the concepts and the documentation, I felt more and more like this is not a problem Byte Buddy was designed for. The majority of examples and questions seem to concentrate on the function delegation to other functions (which actually exist already at compile time, and are only connected to at run time). This is not really convenient in my case, since I have no way of knowing the actual tree I want to convert, at compile time. It is probably possible to use the underlying ASM library, but I would like to avoid handling byte code by myself (and possible successors of mine).
I have a (obviously not working) basic implementation, but I am stuck at the point where I have to provide an Implementation for the intercept() function of the Byte Buddy library. My last state looks like this:
public class ByteBuddyNodeFactory{
#Override
public DynamicNode generateDynamicNode(INode root) {
DynamicNode dynamicNode = null;
try {
Class<?> dynamicType = new ByteBuddy()
.subclass(DynamicNode.class)
.name("DN"+ UUID.randomUUID().toString().replace("-",""))
//this is the point where I have problems
//I don't know how to generate the Implementation for the intercept() function
//An attempt is in the nodeToImplementation() function
.method(ElementMatchers.named("calculateValue")).intercept(nodeToImplementation(root))
.make()
.load(Object.class.getClassLoader())
.getLoaded();
dynamicNode = (DynamicNode) dynamicType.newInstance();
} catch (Exception e) {
System.out.println("Error compiling testclass with bytebuddy: " + e.getMessage());
e.printStackTrace();
}
return dynamicNode;
}
private Implementation.Composable nodeToImplementation(INode node){
if (node.getName().equals("")){
return (Implementation.Composable)FixedValue.value(((ValueNode)node).getValue());
}else{
List<? extends INode> children = node.getChildren();
assert(children.size()==2);
switch (node.getName()){
case ("+"):
//This is the point where I am completely lost
//This return is just the last thing I tried and may be not even correct Java code
// But hopefully at least my intention gets clearer
return (MethodCall.invoke((Method sdjk)-> {
return (nodeToImplementation(children.get(0)).andThen(node.getName().andThen(nodeToImplementation(children.get(1)))));
}));
default:
throw new NotImplementedException();
}
}
}
}
My idea was to concatenate subfunctions together and therefore tried to work with the Composable Implementation. I tried to return a MethodDelegation but as I mentioned I got the feeling that this wouldn't be the right approach. After that I tried MethodCall but I soon realized that I have exactly no idea how to make things work with this one either^^
Question
Is it possible in Byte Buddy to generate a function from a tree structure as dynamically as in Javassist, without calling as many sub functions as I have nodes?
How would I do this, if possible?
And if it is not possible: is it possible with other byte code manipulation libraries like cglib.
I would prefer to stay an abstraction level above byte code, since the study of the underlying concepts should be irrelevant for my problem.
What you are trying to do is not easily possible with Byte Buddy's high-level APIs. Instead, you should assemble a method using StackManipulations if you want to use Byte Buddy. Stack manipulations do still contain Java byte code but these bits should be so trivial that they would be easy to implement.
The reason that Byte Buddy does not aim for this scenario is that you can normally find a better abstraction for your code than to assemble code snippets. Why can your nodes not implement the actual implementation which is then called from your instrumented method? The JIT compiler does typically optimize this code to the same result as your manually inlined code. Additionally, you preserve debuggability and reduce the complexity of your code.

Clean java programming, is it a bad idea to use lambdas to generate method input parameters?

Just a quick question regarding good programming practices,
Performance aside, how much of a good/bad idea could something like this be?
I am oversimplifying the problem to get my point across, but is something like this totally wrong?
public void methodWithInputString(String data) {
// do something with data
}
public void methodThatCallsTheAbove() {
methodWithInputString(
// lambda with no input and a string as output
(() -> {
if (this.conditionIsTrue)
return "Condition is true";
else
return "Condition is false";
}).apply();
);
}
The alternative would simply be:
public void methodThatCallsTheAbove() {
if (this.conditionIsTrue)
methodWithInputString("Condition is true");
else
methodWithInputString("Condition is false");
}
I understand that the second is the obvious/correct approach but in a situation where using the first one makes my code cleaner is it still a nonsensical thing to do?
+1 for Andy Turner remark.
Plus: Avoid object properties reference inside your lambda.
I guess a compilable version of what you are trying to show would be like this:
public class Demo {
private static final Function<Boolean, String> GET_STRING_DEPENDING_ON_BOOLEAN = flagValue -> "Condition is ".concat(String.valueOf(flagValue));
private boolean conditionIsTrue;
public void methodWithInputString(final String data) {
// do something with data
}
public void methodThatCallsTheAbove() {
methodWithInputString(GET_STRING_DEPENDING_ON_BOOLEAN.apply(this.conditionIsTrue));
}
}
The only advantage of doing this (using a lambda instead of a method) is to be able to re use this lambda and chaining something else with.
Example:
methodWithInputString(GET_STRING_DEPENDING_ON_BOOLEAN.andThen(data -> data.concat("somethingelse")).apply(this.conditionIsTrue));

Apache Giraph/Hadoop: Iterating through custom ArrayWritable

I thought this would be simple to implement, but it's starting to be a pain.
I've got a ArrayWritable subclass like so:
public class VertexDistanceArrayWritable extends ArrayWritable {
public VertexDistanceArrayWritable() {
super(VertexDistanceWritable.class);
}
public VertexDistanceArrayWritable(VertexDistanceWritable[] v) {
super(VertexDistanceWritable.class, v);
}
}
And a Writable subclass like so:
public class VertexDistanceWritable implements Writable {
//Implements write, readFields, and some custom functions that aren't used yet
}
In my Giraph compute function, Messages are VertexDistanceArrayWritable's. I want to iterate through every VertexDistanceWritable every message (VertexDistanceArrayWritable). Here is my compute function:
#Override
public void compute(Vertex<Text, MapWritable, FloatWritable> vertex,
Iterable<VertexDistanceArrayWritable> messages) throws IOException {
for(VertexDistanceArrayWritable message : messages) {
for(VertexDistanceWritable distEntry : message) {
//Do stuff with distEntry
}
}
//do other stuff
vertex.voteToHalt();
}
When I compile the code, I get this error:
for-each not applicable to expression type
for(VertexDistanceWritable distEntry : message) {
required: array or java.lang.Iterable
found: VertexDistanceArrayWritable
So now I have a problem. I want to iterate over the arrayWritable sub-class.
I've tried the following:
Change that line to for(VertexDistanceWritable distEntry : message.toArray()) which tells me that for-each not applicaable to type Object (required: array or java.lang.Iterable, found: Object).
Change that line to for(VertexDistanceWritable distEntry : message.get() ), which gives me error: incompatible types -- required: VertexDistanceWritable, found: Writable. This is the strangest problem -- VertexDistanceWritable extends Writable, shouldn't this work fine?
Writing my own custom "get_foo()" function for VertexDistanceWritable, which returns values as a VertexDistanceWritable[]. Of course, values is private, and has no getter function according to the documentation other than get() which I'm already having problems with
I just want a way to iterate over my VertexDistanceArrayWritable class. Is this even possible in Hadoop? It has to be, right? I should be able to iterate over a bunch of elements I made in an array, no? It seems like pretty darn basic stuff.
After about 30 minutes of experimenting and googling, I found out a clue here. Sort of cheesy, but it seems to compile correctly. Basically just use a Writable then cast it to my custom writable.
for(VertexDistanceArrayWritable message : messages) {
for(Writable distWritable : message.get()) {
vertexDistanceWritable distEntry = (VertexDistanceWritable) distWritable;
//do other stuff
}
}
I haven't yet confirmed if it works correctly, I will update and confirm my answer when I can make sure it works.
edit: it works. Might require a copy constructor since I had one for VertexDistanceWritable, but never checked that out.

Categories