рдЬреЗрд╡реАрдПрдо рдХреЗ рд▓рд┐рдП рдЙрдбрд╝рд╛рди рдкрд░ рд╕рдордп рдмрдврд╝ рд░рд╣рд╛ рд╣реИ

рд╢рд╛рдпрдж рд╕рднреА рдХреЛ рдХрднреА-рдХрднреА рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдиреАрдп рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рд╕рдордп рдХреЗ рд╣рд╕реНрддрд╛рдВрддрд░рдг рдХреА рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдЬреВрдЭрдирд╛ рдкрдбрд╝рддрд╛ рдерд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдЬ рдХреА рддрд╛рд░реАрдЦ рд╕реЗ рдПрдХ рд╕рдкреНрддрд╛рд╣ рдореЗрдВ рд╕рд░реНрд╡рд░ рдХреИрд╕реЗ рднреБрдЧрддрд╛рди рдХрд░рддрд╛ рд╣реИред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╕рд┐рд╕реНрдЯрдо рд╕рдордп рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЙрд╕рдХреА рдХрдИ рдХрдорд┐рдпрд╛рдВ рд╣реИрдВред рдХреБрдЫ рдХрд╛рд░реНрдпрдХреНрд░рдо, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдХрд╛рдЗрдк рд╡рд┐рдлрд▓ рд╣реЛрдиреЗ рд▓рдЧрддреЗ рд╣реИрдВ, рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдпрд╛ рдЕрддреАрдд рдореЗрдВ рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдмрдЪрд╛рддреЗ рд╣реИрдВред рд╕рд╛рде рд╣реА, рд╕рд┐рд╕реНрдЯрдо рдиреАрддрд┐рдпреЛрдВ рдХреЛ рд╣рд░ 5 рдорд┐рдирдЯ рдореЗрдВ рдПрдХ рдХреЙрд░реНрдкреЛрд░реЗрдЯ рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рд╕рдордп рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдпрд╣ рдХреБрдЫ рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдФрд░, рдХреБрдЫ рдШрдВрдЯреЛрдВ рдХреЗ рднрдпрдВрдХрд░ рдЧреБрдЧрд▓реА рдХреЗ рдмрд╛рдж, рдПрдХ рдЫреЛрдЯрд╛ рдЬрд╛рд╡рд╛-рдПрдЬреЗрдВрдЯ рд▓рд┐рдЦрд╛ рдЬреЛ рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдЬреЗрд╡реАрдПрдо рдХреЗ рд▓рд┐рдП рд╕рдордп рдмрджрд▓рддрд╛ рд╣реИ рдФрд░ рдорд╢реАрди рдХреА рд╕рд┐рд╕реНрдЯрдо рддрд┐рдерд┐ рдХреЛ рдирд╣реАрдВ рдЫреВрддрд╛ рд╣реИред рд╡рд╛рдВрдЫрд┐рдд рддрд┐рдерд┐ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рд▓реА рдЧрдИ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЗрд╕рдХреА рдЕрдВрддрд┐рдо рд╕рдВрд╢реЛрдзрди рддрд┐рдерд┐ рд╣рд░ рдмрд╛рд░ рдЬрд╛рдВрдЪреА рдЬрд╛рддреА рд╣реИред рд╢рд╛рдпрдж рдпрд╣ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдФрд░ рд╕рдмрд╕реЗ рддреЗрдЬрд╝ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрд░реЛрддреЛрдВ рдХреЛ рд▓реЗрдиреЗ рд╕реЗ рдЖрдк рдпрд╣ рддрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХреИрд╕реЗ рд╣реЛрдЧрд╛ рдФрд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рди рдХреЗрд╡рд▓ рддрд╛рд░реАрдЦ рдХреА рд╢рд┐рдлреНрдЯ, рдмрд▓реНрдХрд┐ рд╕рдордп рднреА рдЬреЛрдбрд╝реЗрдВред рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рднреА рд╣реИ рдЬреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рджрд┐рдирд╛рдВрдХ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдПрдЬреЗрдВрдЯ рдХреЗ рдХрд╛рдо рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдЗрдВрд╕реНрдЯреНрд░реВрдореЗрдВрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдпрд╣ MySystem.currentTimeMillis рдХреЗ рдореЗрд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде System.currentTimeMillis рдХреЛ рдХреЙрд▓ рдХреА рдЬрдЧрд╣ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рддрд╛рд░реАрдЦ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЕрдм рдереЛрдбрд╝рд╛ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдЬрд╛рд╡рд╛ рдПрдЬреЗрдВрдЯ рдХрд╛ рдореБрдЦреНрдп рд╡рд░реНрдЧ рдореЗрдирдХреНрд▓рд╛рд╕ рд╣реИ, рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░, рдЬреЗрд╡реАрдПрдо рдЕрдкрдиреЗ рдореБрдЦреНрдп рдкреНрд░реАрдорд┐рдпрд░ рд╡рд┐рдзрд┐ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛:
public class MainClass { private static Instrumentation instrumentation; // ,      System.currentTimeMillis   private static ClassTransformer transformer; //   ClassFileTransformer public static File FILE = null; // ,       public static void premain(String args, Instrumentation inst) throws Exception { System.out.println("dateshift agent starting"); if (args != null && args.length() > 0) { //    ,         String path = args; System.out.println("Using dateshift.txt path from args: '" + path + "'"); FILE = new File(path); } else { //   ,  -   dateshift.txt,       bin tomcat-a FILE = new File(new File(System.getenv("CATALINA_HOME"), "bin"), "dateshift.txt"); } System.out.println("Path for dateshift.txt: '" + FILE.getAbsolutePath() + "'"); instrumentation = inst; //  ,   JVM transformer = new ClassTransformer(); instrumentation.addTransformer(transformer, true); //  ,      ClassTransformer    Class[] classes = inst.getAllLoadedClasses(); //     ,    . ,    ,     ArrayList<Class> classList = new ArrayList<Class>(); for (int i = 0; i < classes.length; i++) { if (inst.isModifiableClass(classes[i])) { //    ,     classList.add(classes[i]); } } // Reload classes, if possible. Class[] workaround = new Class[classList.size()]; try { inst.retransformClasses(classList.toArray(workaround)); //    } catch (UnmodifiableClassException e) { System.err.println("MainClass was unable to retransform early loaded classes: " + e); } } } 


рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрд▓рд╛рд╕рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдорд░ рдХреНрд▓рд╛рд╕ рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреИрд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИред рдпрд╣ MySystem.currentTimeMillis рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХреЗ рд╕рд╛рде System.currentTimeMillis рдХреЛ рд╕рднреА рдХреЙрд▓ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП javassist рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓рддрд╛ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд╣реИ:
 public class ClassTransformer implements ClassFileTransformer { public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if(className.startsWith("ru/javaorca/")) return null; //    try { ClassPool pool = ClassPool.getDefault(); CtClass s1 = pool.get("java.lang.System"); CtMethod m11 = s1.getDeclaredMethod("currentTimeMillis"); //  ,     CtClass s2 = pool.get("ru.javaorca.MySystem"); CtMethod m21 = s2.getDeclaredMethod("currentTimeMillis"); //  ,      CodeConverter cc = new CodeConverter(); cc.redirectMethodCall(m11, m21); //        CtClass cl = pool.makeClass(new ByteArrayInputStream(classfileBuffer), false); //  ,    if(cl.isFrozen()) return null; CtConstructor[] constructors = cl.getConstructors(); //     for(CtConstructor constructor : constructors) { constructor.instrument(cc); //   } CtMethod[] methods = cl.getDeclaredMethods(); //     for(CtMethod method : methods) { method.instrument(cc); //   } classfileBuffer = cl.toBytecode(); } catch (Exception ex) { System.out.println("Exception: " + ex); ex.printStackTrace(); } return classfileBuffer; //    } } 


MySystem рд╡рд░реНрдЧ, рдЬрд┐рд╕реЗ рд╣рдо рд╕рд┐рд╕реНрдЯрдо рдПрдХ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИ:
 public class MySystem { public static long currentTimeMillis() { long res = System.currentTimeMillis(); //     long res1 = DateShift.getTime(res); //     return res1; //    } } 


рдЕрдВрддрд┐рдо DateShift рдХреНрд▓рд╛рд╕ рдмрдиреА рд╣реБрдИ рд╣реИ, рдЬреЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рд╕рдордп рдХреЛ рд▓реЛрдб рдХрд░рддреА рд╣реИ рдФрд░ рд╕рд┐рд╕реНрдЯрдо рддрд┐рдерд┐ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рдордп рдСрдлрд╕реЗрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рддреА рд╣реИред
 public class DateShift { private static volatile long lastModified = 0; //       private static volatile long timeShift = 0; //      private static final long timeFilter = 86400000L; // 1000*60*60*24,        public static long getTime(long currentTime) { // ,    long res = currentTime; if ((lastModified > 0 && !MainClass.FILE.exists()) || lastModified < MainClass.FILE.lastModified()) { //   ,       System.out.println("File modification detected"); synchronized (MainClass.FILE) { if (MainClass.FILE.exists()) { lastModified = MainClass.FILE.lastModified(); long newTime = readDateFromFile(); //     if (newTime > 0) { timeShift = newTime - ((res / timeFilter) * timeFilter); //          } } else { lastModified = 0; //   ,     timeShift = 0; } } } if (timeShift != 0) { res += timeShift; //   } return res; } private static long readDateFromFile() { // ,     System.out.println("Reading data from file '" + MainClass.FILE.getAbsolutePath() + "'"); long res = 0; BufferedReader br = null; try { br = new BufferedReader(new FileReader(MainClass.FILE)); String line = br.readLine(); //      if (line != null && !line.trim().isEmpty()) { SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT); //     dd.MM.yyyy try { Date date = DATE_FORMAT.parse(line); System.out.println("Loaded date from file: " + date); Calendar c = Calendar.getInstance(); c.setTime(date); long offset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET); //       .   ,    JVM     System.out.println("Offset: " + offset); res = c.getTime().getTime(); res += offset; } catch (ParseException e) { System.out.println("ParseException: " + e); e.printStackTrace(System.out); } } else { System.out.println("File is empty"); } } catch (IOException e) { System.out.println("IOException: " + e); e.printStackTrace(System.out); } finally { if (br != null) { try { br.close(); } catch (IOException e) { System.out.println("IOException: " + e); e.printStackTrace(System.out); } } } return res; } } 


рдПрдЬреЗрдВрдЯ рдорд╛рд╡реЗрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рд╕рднреА рдирд┐рд░реНрднрд░рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рдЬрд╛рд░ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рддрд╛ рд╣реИред рдореИрдВ рдЗрд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдирд╣реАрдВ рдЪрд┐рддреНрд░рд┐рдд рдХрд░реВрдВрдЧрд╛, рдЖрдк рдЗрд╕реЗ рдмрд┐рдЯрдХреЙрдЗрди рдкрд░ рд╕реНрд░реЛрдд рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред

рдПрдЬреЗрдВрдЯ рдХреЛ рдЕрдкрдиреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ jvm рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:
 -javaagent:D:\development\srv\dateshift-1.4-jar-with-dependencies.jar=D:\development\srv\dateshift.txt 


рд╡рд╣ рд╕рдм рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдПрдЬреЗрдВрдЯ рдХрд╛рдлреА рд╕рд░рд▓ рдирд┐рдХрд▓рд╛ рдФрд░ рдЖрдкрдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рдЕрдиреБрд░реВрдк рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдПрдХ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рджреЛрд╖ рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рд╡рд░реНрддрдорд╛рди рддрд┐рдерд┐ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рдордп рдХреЛ рдкреАрдЫреЗ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрд╡реЗрджрди рдереЛрдбрд╝рд╛ рдЫреЛрдЯрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдареАрдХ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдпрд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╡реЗ рдмрд╕ рдЫреЛрдЯреА рдЧрд╛рдбрд╝реА рдХреЗ рд╕рдорд╛рди рд╣реИрдВ рдпрджрд┐ рдЖрдк рд╕рд┐рд╕реНрдЯрдо рдХреА рддрд╛рд░реАрдЦ рдХреЛ рд╕реАрдзреЗ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд╢рд┐рдлреНрдЯ рдХрд░рддреЗ рд╣реИрдВред

рд╕реВрддреНрд░ https://bitbucket.org/javaorca/dateshift/src рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ

Source: https://habr.com/ru/post/In170401/


All Articles