ClassVisitor does not give the private methods with content of Lambda expression - java-bytecode-asm

This ClassVisitor never shows the generated private methods that hold the content of Lambda expressions.
The ClassVisitor is used like this (i cut the function, i just want to know why the ClassVisitor does not visit the private void lambda, it is working with the other methods like charm).
ClassReader classReader = new ClassReader(className);
ClassWriter classWriter = new ClassWriter(4);
CustomClassVisitor customClassVisitor = new CustomClassVisitor(classWriter);
classReader.accept(customClassVisitor,0);
modifiedClass = classWriter.toByteArray();
The ClassVisitor:
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import static org.objectweb.asm.Opcodes.ASM7;
public class CustomClassVisitor extends ClassVisitor {
public CustomClassVisitor(ClassWriter classWriter) {
super(ASM7, classWriter);
}
public MethodVisitor visitMethod(
int access,
String name,
String desc,
String signature,
String[] exceptions) {
final MethodVisitor methodVisitor = cv.visitMethod(access, name, desc, signature, exceptions);
return methodVisitor;
}
}
They are in bytecode:
private void lambda$main$0(java.lang.Integer)
descriptor: (Ljava/lang/Integer;)V
flags: (0x1002) ACC_PRIVATE, ACC_SYNTHETIC
Code:
stack=3, locals=2, args_size=2
0: aload_0
1: bipush 100
3: aload_1
4: invokevirtual #11 // Method java/lang/Integer.intValue:()I
7: invokevirtual #4 // Method wait:(II)V
10: return
LineNumberTable:
line 45: 0
line 46: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this Lorg/Lambda;
0 11 1 elem Ljava/lang/Integer;
How could i see this method in ASM ClassVisitor? Is there an extra parameter? ClassWriter is in mode 4.

Related

Transform PCollection<KV> to custom class

My goal is to read a file from GCS and write it to Cassandra.
New to Apache Beam/Dataflow, I could find most of the hand on build with Python. Unfortunately CassandraIO is only Java native with Beam.
I used the word count example as a template and try to get rid of the TextIO.write() and replace it with a CassandraIO.<Words>write().
Here my java class for the Cassandra table
package org.apache.beam.examples;
import java.io.Serializable;
import com.datastax.driver.mapping.annotations.Column;
import com.datastax.driver.mapping.annotations.PartitionKey;
import com.datastax.driver.mapping.annotations.Table;
#Table(keyspace = "test", name = "words", readConsistency = "ONE", writeConsistency = "QUORUM",
caseSensitiveKeyspace = false, caseSensitiveTable = false)
public class Words implements Serializable {
// private static final long serialVersionUID = 1L;
#PartitionKey
#Column(name = "word")
public String word;
#Column(name = "count")
public long count;
public Words() {
}
public Words(String word, int count) {
this.word = word;
this.count = count;
}
#Override
public boolean equals(Object obj) {
Words other = (Words) obj;
return this.word.equals(other.word) && this.count == other.count;
}
}
And here the pipeline part of the main code.
static void runWordCount(WordCount.WordCountOptions options) {
Pipeline p = Pipeline.create(options);
// Concepts #2 and #3: Our pipeline applies the composite CountWords transform, and passes the
// static FormatAsTextFn() to the ParDo transform.
p.apply("ReadLines", TextIO.read().from(options.getInputFile()))
.apply(new WordCountToCassandra.CountWords())
// Here I'm not sure how to transform PCollection<KV> into PCollection<Words>
.apply(MapElements.into(TypeDescriptor.of(Words.class)).via(PCollection<KV<String, Long>>)
}))
.apply(CassandraIO.<Words>write()
.withHosts(Collections.singletonList("my_ip"))
.withPort(9142)
.withKeyspace("test")
.withEntity(Words.class));
p.run().waitUntilFinish();
}
My understand is to use a PTransform to pass from PCollection<T1> from PCollection<T2>. I don't know how to map that.
If it's 1:1 mapping, MapElements.into is the right choice.
You can either specify a class that implements SerializableFunction<FromType, ToType>, or simply use a lambda, for example:
.apply(MapElements.into(TypeDescriptor.of(Words.class)).via(kv -> new Words(kv.getKey(), kv.getValue()));
Please check MapElements for more information.
If the transformation is not one-to-one, there are other available options such as FlatMapElements or ParDo.

DriverManager.getConnection(url, "username", "password. ");, Javap Mitigation

Hard-Coding using JavaDB, and netbeans. I wrote a simple table, then I wrote a simple java program to run and connect to the database, code seems to be running well. I wrote the code hard-coded purposefully with the username/password to the database. Wrote the code, an, awesome. I am using terminal and javap -c, with DriverManager.getConnection(url, "username", "password. ");o read all the file, Im hoping that's considered hard-coded hacking, I need a way to mitigate it, or patch it. I was looking at Argon2 for java, but simply can't understand it yet. These are pics of running the code, connection, database, and in terminal I ran javap -c and it red me out the username/password info, how can I block. AlsoI installed a Debugging Plugin into NB tjat worked once and did like javap, but it's only worked once. if some one could help me with it or a dfferent type of mitigation - patch Id really appreciate it.
Main Code with exception:
import java.sql.SQLException;
public class HardCodeMitigation {
public static void main(String[] args) throws SQLException {
// TODO code application logic here
abc a1 = new abc();
}
}
Second code w/DriverMan with passwords Hard-coded
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
class abc {
public abc() throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:derby://localhost:1527/IT_Entity", "cain", "cain");
System.out.println("Connection Created");
}
}
Javap - c showing passwords: Chads - MacBook - Pro: ~chadbyars$ cd / Users / chadbyars / NetBeansProjects / hardcodemitigation / src
Chads - MacBook - Pro: src chadbyars$ javac abc.java
Chads - MacBook - Pro: src chadbyars$ java abc
Error: Main method not found in class abc, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
Chads - MacBook - Pro: src chadbyars$ javap - c abc
Compiled from "abc.java"
class abc {
public abc() throws java.sql.SQLException;
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: ldc # 2 // String jdbc:derby://localhost:1527/IT_Entity
6: ldc #3 // String cain
8: ldc # 3 // String cain
10: invokestatic #4 // Method java/sql/DriverManager.getConnection:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/sql/Connection;
13: astore_1
14: getstatic # 5 // Field java/lang/System.out:Ljava/io/PrintStream;
17: ldc #6 // String Connection Created
19: invokevirtual # 7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
22: return
}
Chads - MacBook - Pro: src chadbyars$

Update a mixed type activity in GetStream.IO using the java stream client loses the type attribute

I have taken the MixedType example code that comes with the java stream client (https://github.com/GetStream/stream-java) and added a update step using updateActivities. After the update the activity stored in stream loses the 'type' attribute. Jackson uses this attribute when you get the activities again and it is deserialising them.
So I get:
Exception in thread "main" Disconnected from the target VM, address: '127.0.0.1:60016', transport: 'socket'
com.fasterxml.jackson.databind.JsonMappingException: Could not resolve type id 'null' into a subtype of [simple type, class io.getstream.client.apache.example.mixtype.MixedType$Match]
at [Source: org.apache.http.client.entity.LazyDecompressingInputStream#29ad44e3; line: 1, column: 619] (through reference chain: io.getstream.client.model.beans.StreamResponse["results"]->java.util.ArrayList[1])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.unknownTypeException(DeserializationContext.java:849)
See here where I have updated the example:
https://github.com/puntaa/stream-java/blob/master/stream-repo-apache/src/test/java/io/getstream/client/apache/example/mixtype/MixedType.java
Any idea what is going on here?
The issue here is originated by Jackson which cannot get the actual instance type of an object inside the collection due to the Java type erasure, if you want to know more about it please read this issue: https://github.com/FasterXML/jackson-databind/issues/336 (which also provides some possible workarounds).
The easiest way to solve it, would be to manually force the value of the property type from within the subclass as shown in the example below:
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
#JsonSubTypes({
#JsonSubTypes.Type(value = VolleyballMatch.class, name = "volley"),
#JsonSubTypes.Type(value = FootballMatch.class, name = "football")
})
static abstract class Match extends BaseActivity {
private String type;
public String getType() {
return type;
}
}
static class VolleyballMatch extends Match {
private int nrOfServed;
private int nrOfBlocked;
public VolleyballMatch() {
super.type = "volley";
}
public int getNrOfServed() {
return nrOfServed;
}
public void setNrOfServed(int nrOfServed) {
this.nrOfServed = nrOfServed;
}
public void setNrOfBlocked(int nrOfBlocked) {
this.nrOfBlocked = nrOfBlocked;
}
public int getNrOfBlocked() {
return nrOfBlocked;
}
}
static class FootballMatch extends Match {
private int nrOfPenalty;
private int nrOfScore;
public FootballMatch() {
super.type = "football";
}
public int getNrOfPenalty() {
return nrOfPenalty;
}
public void setNrOfPenalty(int nrOfPenalty) {
this.nrOfPenalty = nrOfPenalty;
}
public int getNrOfScore() {
return nrOfScore;
}
public void setNrOfScore(int nrOfScore) {
this.nrOfScore = nrOfScore;
}
}

Are accessors / mutators auto-defined in Groovy?

In the section on handling Java Beans with Groovy of Groovy In Action, I found this script (slightly modified):
class Book{
String title
}
def groovyBook = new Book()
// explicit way
groovyBook.setTitle('What the heck, really ?')
println groovyBook.getTitle()
// short-hand way
groovyBook.title = 'I am so confused'
println groovyBook.title
There are no such methods in the class Book so how does that work ?
Yes, they are auto defined and calling book.title is actually calling book.getTitle()
See http://groovy.codehaus.org/Groovy+Beans
You can see this in action with the following script:
def debug( clazz ) {
println '----'
clazz.metaClass.methods.findAll { it.name.endsWith( 'Name' ) || it.name.endsWith( 'Age' ) }.each { println it }
}
class A {
String name
int age
}
debug( A )
// Prints
// public int A.getAge()
// public java.lang.String A.getName()
// public void A.setAge(int)
// public void A.setName(java.lang.String)
// Make name final
class B {
final String name
int age
}
debug( B )
// Prints
// public int B.getAge()
// public java.lang.String B.getName()
// public void B.setAge(int)
// Make name private
class C {
private String name
int age
}
debug( C )
// Prints
// public int C.getAge()
// public void C.setAge(int)
// Try protected
class D {
protected String name
int age
}
debug( D )
// Prints
// public int D.getAge()
// public void D.setAge(int)
// And public?
class E {
public String name
int age
}
debug( E )
// Prints
// public int E.getAge()
// public void E.setAge(int)
Several notes:
For all property fields(public ones only), there are autogenerated accesors.
Default visibility is public. So, you should use private/protected keyword to restrict accessor generation.
Inside an accessor there is direct field access. like this.#title
Inside a constructor you have direct access to! This may be unexpected.
For boolean values there are two getters with is and get prefixes.
Each method with such prefixes, even java ones are treated as accessor, and can be referenced in groovy using short syntax.
But sometimes, if you have ambiguous call there may be class cast exception.
Example code for 4-th point.
class A{
private int i = 0;
A(){
i = 4
println("Constructor has direct access. i = $i")
}
void setI(int val) { i = val; println("i is set to $i"); }
int getI(){i}
}
def a = new A() // Constructor has direct access. i = 4
a.i = 5 // i is set to 5
println a.i // 5
​
4-th note is important, if you have some logic in accessor, and want it to be applied every time you call it. So in constructor you should explicit call setI() method!
Example for 7
class A{
private int i = 0;
void setI(String val) { println("String version.")}
void setI(int val) { i = val; println("i is set to $i"); }
}
def a = new A()
a.i = 5 // i is set to 5
a.i = "1s5" // GroovyCastException: Cannot cast object '1s5' with class 'java.lang.String' to class 'int'
​
So, as I see property-like access uses first declared accessor, and don't support overloading. Maybe will be fixed later.
Groovy generates public accessor / mutator methods for fields when and only when there is no access modifier present. For fields declared as public, private or protected no getters and setters will be created.
For fields declared as final only accessors will be created.
All that applies for static fields analogously.

NDepend CQL reports methods as using Boxing/Unboxing incorrectly

In NDepend 4 (v4.1.0.6871) I am using the default Design query "Boxing/unboxing should be avoided":
warnif percentage > 5 from m in Application.Methods where
m.IsUsingBoxing ||
m.IsUsingUnboxing
select new { m, m.NbLinesOfCode, m.IsUsingBoxing, m.IsUsingUnboxing }
It is reporting the following method (Inspired by and stolen from Jon Skeet's MiscUtil) as using boxing:
public static void ThrowIfNull<T>(this T target, string name) where T : class
{
if (target == null)
{
throw new ArgumentNullException(name ?? string.Empty);
}
}
I don't understand how this method is possibly using boxing. I am not using a cast anywhere.
I tried the following version just in case the null coalescing operator was using boxing somehow behind the scenes:
public static void ThrowIfNull<T>(this T target, string name) where T : class
{
if (target == null)
{
throw new ArgumentNullException(name);
}
}
... but I had no luck with that either, NDepend still reported that the method was using boxing.
Any ideas?
By decompiling this method with .NET Reflector we see that indeed this method is using the box IL instruction. Despite the fact that you are using the class generic constraint, the compiler still emits a box instruction for verifiability issue. More explanation on this here.
.method public hidebysig static void ThrowIfNull<class T>(!!T target, string name) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()
.maxstack 2
.locals init (
[0] bool flag)
L_0000: nop
L_0001: ldarg.0
L_0002: box !!T <-----------
L_0007: ldnull
L_0008: ceq
L_000a: ldc.i4.0
L_000b: ceq
L_000d: stloc.0
L_000e: ldloc.0
L_000f: brtrue.s L_0022
L_0011: nop
L_0012: ldarg.1
L_0013: dup
L_0014: brtrue.s L_001c
L_0016: pop
L_0017: ldsfld string [mscorlib]System.String::Empty
L_001c: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string)
L_0021: throw
L_0022: ret
}

Resources