java bytecode manipulate; insert Print code after every java code - java

I want to insert Print code after every java code.
For example:
public void myMethod() {
Integer i = 0;
Long l = 0L;
Date date = new Date();
}
to:
public void myMethod() {
Integer i = 0;
System.out.println("test");
Long l = 0L;
System.out.println("test");
Date date = new Date();
System.out.println("test");
}
how should I do?Can you help me?

One way to a solution in the compiler
1 parse your code:
Best way to parse Java in Java
2 insert automatically code:
use JET for example
https://eclipse.org/articles/Article-JET2/jet_tutorial2.html
SECOND SOLUTION
create and put some annotation (by hand)
RUNTIME SOLUTION
you have to investigate bytecode.
Some links:
http://web.cs.ucla.edu/~msb/cs239-tutorial/
see the chapter: Generating Call Traces
And posts around this tag:
https://stackoverflow.com/questions/tagged/java-bytecode-asm

Related

Java Change return type of library package

In my Java project,
I downloaded the following package through Maven:
https://github.com/binance-exchange/binance-java-api
With this API,
I am capable of getting Candlesticks from Binance,
however;
the function:
Get weekly candlesticks
returns a List<Candlestick>,
but I created my own class Candlestick that contains everything from
their class Candlestick,
except mine has a few more attributes.
Now I tried the following code:
public static List<Candlestick> getCandlesticks(
String symbol,
int limit,
LocalDateTime startLocalDateTime,
LocalDateTime endLocalDateTime)
{
BinanceApiClientFactory factory =
BinanceApiClientFactory.newInstance(API_KEY, SECRET);
BinanceApiRestClient client = factory.newRestClient();
CandlestickInterval interval = CandlestickInterval.HOURLY;
long startTime = startLocalDateTime.toEpochSecond(ZoneOffset.UTC) * 1000;
long endTime = endLocalDateTime.toEpochSecond(ZoneOffset.UTC) * 1000;
return client.getCandlestickBars(symbol, interval, limit, startTime, endTime);
}
But that gives me the error:
I can't edit the source file,
because it is read only,
so how can I get the function to return my List<Candlestick> class?
It's not possible. Your CandleStick class and the library's CandleStick class are different classes. That's exactly what the error message is telling you. You will also notice that the packages of the classes are different.
You need to convert each item in the list to "adapt" the return type to your expected type. You could use the Streams API, for instance:
return client.getCandlestickBars(symbol, interval, limit, startTime, endTime)
.stream()
.map(cs -> convertMyCandleStick(cs))
.collect(Collectors.toList());
convertMyCandleStick will probably look something like this:
private static Candlestick convertMyCandleStick(final com.binance.api.client.domain.market.Candlestick candlestick) {
if (candlestick == null) return null;
final Candlestick converted = new Candlestick();
converted.setId(candlestick.getId());
converted.setName(candlestick.getName());
// repeat for all properties ...
return converted;
}
If the properties in both classes have the same name and type, you can use BeanUtils#copyProperties as explained in the answers to the question Copy POJO content from one bean to another.

How to write a java function in Spring data derivative

Right now I write the function to get the number of working days myself. Instead of course it is much better to make use of Spring data and let the database make the calculation.
So how could I write the second function in Spring data.
It should be something like. Count by Date Distinct group by date from WorkingDay . A workingDayObject can occur more than once per day if somebody worked on different projects . That's way I use a hashset in my function to get just the days.
private double calculateOvertimeHours(WorkingMonth month)
{
double workedHours = Util.convertTimeToDoubleDecimal(month.getWorkedHours());
//Here I use a Spring data method as you can see
List<WorkingDay> lstWorkingDays = workingDayDao.findByWorkingMonthOrderByDateAsc(month);
return workedHours - calcNumberWorkDays(lstWorkingDays) * 8;
}
private int calcNumberWorkDays(List<WorkingDay> lstWorkingDays)
{
Set<Integer> hashSetDays = new HashSet<Integer>();
Calendar cal = Calendar.getInstance();
for(WorkingDay workingDay : lstWorkingDays)
{
cal.setTime(workingDay.getDate());
hashSetDays.add(cal.get(Calendar.DAY_OF_MONTH));
}
return hashSetDays.size();
}

Java static variable update with quartz scheduler

I have a JobClass wherein I am calling another class named as MainClass. The quartz trigger schedule to run the Main class via JobClass every 5 minutes. Now in the main class I have to collect the current date time something like below:-
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd/hh/mm/ss");
Calendar calendar = Calendar.getInstance();
String CurrentDateTime = dateFormat.format(calendar.getTime());
public String[] splitMe = CurrentDateTime.split("/");
public String year = splitMe[0];
public String month = splitMe[1];
public String day = splitMe[2];
public String hour = splitMe[3];
public String minute = splitMe[4];
public String second = splitMe[5];
String FilePrefix = year.concat(month).concat(day).concat("_").concat(hour).concat(minute).concat(second);
String FilePrefix4ControlFile = year.concat(month).concat(day).concat(" ").concat(hour).concat(minute).concat(second);
String EarliestTime = year.concat("-").concat(month).concat("-").concat(String.valueOf(Integer.parseInt(day) - 1));
String LatestTime = year.concat("-").concat(month).concat("-").concat(day);
This way I can get all my date time individual variable to create some strings with different combinations. Every single job runs I need to have a unique set of values however whatever number of times these variables are called within one job run then the values should be same.
Now I tried doing it using Static variables which kind of solved one problem of having same values during 1 run. However as the static variables are created on class initialisation ( main class) then they will always have same value unless the class is reloaded which I don't want to do , indeed not that easily possible in java.
I am sure I am doing some silly mistake, any pointers on this will be helpful.
PS: I just started Java by my own recently.
Thanks guys!
RJay

making a method thread safe even when method is called by makeing multiple instances of class

I want to have thread save method that returns a unique current Timestamp.Even when the method is called by same time i want to get a unique current datetime.Even if this method is called by making multiple instances of MyClass i want it be be thread safe always
class Myclass{
Date getUniquetimeStam(){
synchronized(Myclass.class){
//return date here
}
}
Now if i make 2 instances of Myclass and call getUniqueStam at same ,is it gaurented to return uniue date time.
You can't guarantee unique time for each call. But you can for instance increment it manually if it didn't change yet:
private AtomicLong lastTime = new AtomicLong();
long getUniquetimeStam() {
while (true) { // way of working with atomics, but they are really fast
long now = System.currentTimeMillis();
long last = lastTime.get();
if (last < now) {
if (lastTime.compareAndSet(last, now))
return now;
} else
return lastTime.incrementAndGet();
}
}
No, you are not guaranteed. If your computer is fast enough then both method calls can happen in same millisecond and produce identical Date object.
You have 2 options here:
Use UUID instead of date. Read more about it here . UUID by specification is guaranteed to be unique each time you generate it - so it's the safest and easiest option you can get.
Store the date object, synchronize on it, and check if it's the same. Here's an example:
.
class Myclass {
//Static to make it possible to synchronize between instances of Myclass
static Date lastDate;
Date getUniqueTimeStamp() {
synchronized (Myclass.lastDate) {
Date newDate = new Date();
if (newDate.getTime() <= Myclass.lastDate.getTime()) {
newDate.setTime(Myclass.lastDate.getTime()+1);
}
Myclass.lastDate.setTime(newDate.getTime());
return newDate;
}
}
}
Not cool though - you can add a delay and then create the Data.
class Myclass {
Date getUniquetimeStam() {
//in try catch
Thread.sleep(100);
//
new Date();
}
}
Could you just change it to return a new instance of Date on every call?
class Myclass {
Date getUniquetimeStam() {
new Date();
}
}

Best method to create a new instance based on precondition

Hi my question is this. Suppose you have an interface that defines how a converter would be implemented. This interface could have a method loadDocument() and another convert(). Now suppose we want to have multiple converters, ConvertHTML2DOC, ConvertXML2HTML e.t.c you get the idea.
Suppose you get the two formats you need to convert in 2 strings (doesn't matter HOW you get them). Now you need to create an instance of your converter and convert the documents.
My question is which is better: to actually create an elaborate if statement or to load the classes through reflection with the Class class? to demonstrate I wrote a little example of what I mean. In my example I have 2 classes P1 and P2 that share an interface. I also create 50000 of them to show of the speed differences. As it turns out the normal invocation is slightly faster, but I think that in a complex example such as the one i mentioned in the beginning, the benefits of creating the classes through the Class method is more convenient and more maintainable. What are your thoughts?
import java.util.*;
public class Test {
public static void main(String[] args) {
try {
Random r = new Random();
Date test1start = new Date();
for (int i = 0; i<= 50000; i++){
Printable p = (Printable)Class.forName("P"+(r.nextInt(2)+1)).newInstance();
System.out.println(p.getString());
}
Date test1stop = new Date();
Date test2start = new Date();
for (int i = 0; i<= 50000; i++){
Printable p;
if (r.nextInt(2) == 0 ) {
p = new P1();
} else {
p = new P2();
}
System.out.println(p.getString());
}
Date test2stop = new Date();
System.out.println("Test with 'Class' invocation took "+(test1stop.getTime()-test1start.getTime())+" milliseconds.");
System.out.println("Test with 'normal' invocation took "+(test2stop.getTime()-test2start.getTime())+" milliseconds.");
} catch (Exception e) {
}
}
}
interface Printable {
public String getString();
}
class P1 implements Printable {
public String getString(){
return "1";
}
}
class P2 implements Printable {
public String getString(){
return "2";
}
}
You should definitely follow the advice from Javier - a registry of factories is the right way to go for this problem. I've implemented it that way many times in the past, be for format translation or some other extensible "predicate" based factory solution (eg, automatic GUI generation based on reflection information).
I would however suggest one addition to the design - the introduction of a common domain model (CDM) that is targeted by all translators. Say that you have formats A, B and C an that you need to support transformation between each - you get all the permutations:
A -> B
A -> C
B -> A
B -> C
C -> A
C -> B
As the number of format grows, you get an explosion of transformations! A better idea is to separate each transformation into two parts - lets call it an importer and an exporter. The importer converts a format to the common domain model (CDM) while an export converts the from the CDM to some format.
As an example, we decompose the conversion from A to B into the following:
A --> CDM (this is an import)
CDM --> B (this is an export)
Now when you want to add a new format you need only write an importer and an exporter but you get translation to/from all other formats! Talk about extensible! It also allows for formats for which yo can read but not write and vice versa.
So, the solution would be to have a registry of importer factories and a registry of exporter factories.
definitely use a factory method; but instead of a "big if", or name-mangling, use a "class registration" method. for this, the factory class maintains a table where each concrete class registers it's condition (in your case it's the source and target names) and the constructor (it's a 'condition->constructor' dictionary). the factory itself simply constructs the dictionary key and fetches the constructor it needs.
one big advantage is that each concrete class encapsulates the condition it solves, and you can add more without changing the factory method.
Try something like this, compile time safety, with the one-lineness of the Class.forName.
public class PrintableFactory
{
public enum Type
{
HTML,
DOC,
}
public static Printable getPrintable(final Type from, final Type to)
{
final Printable printable;
if(from == HTML && to == DOC)
{
printable = new HtmlToDoc();
}
else if(from == DOC && to == HTML)
{
printable = new DocToHTML();
}
else
{
// you decide if you want runtime or compile time exception handling
// could also return numm but I don't like that myself.
throw new ImpossibleConversionException(from, to);
}
return (printable);
}
}

Categories