如何拦截类加载并在那里更改字符串文字?

时间:2018-08-11 15:22:54

标签: java

是否可以拦截类加载并在动态加载jar文件时更改字符串文字? 我一直在寻找问题的答案,但没有找到我需要的==

为什么需要它:我使用一个服务器应用程序(jar文件),而该服务器应用程序使用其他插件(jar文件)。服务器应用程序和插件未本地化。 我很疲倦地要求这些应用程序的作者进行本地化。他们不想这样做,因为这将花费很多时间。所以,我正在考虑自己做。
我知道有些应用程序可以更改jar文件中的字符串文字。但是他们以交互方式进行操作,并且没有配置以“批处理”模式执行此操作。另外,我需要本地化的应用程序经常会更新,并且本地化将不得不再次进行。

因此,我想在加载类时动态地“即时”执行此操作。但是我不知道怎么=(
我写了一个小代码示例来展示我的启动器如何执行主服务器应用程序,然后再加载其他插件

我的启动器(MyLauncher.jar):

package com.example.mylauncher;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

public class Main {
    public static void main(String[] args) {
        System.out.println("I am MyLauncher");

        // ... here we need some preparations for our interception to change string literals ... 

        // Now run main from SomeApplication.jar
        try {
            File myJar = new File("SomeApplication.jar");
            URLClassLoader child = new URLClassLoader(new URL[]{myJar.toURI().toURL()});
            Class<?> classToLoad = Class.forName("com.example.someapplication.Main", true, child);
            Method method = classToLoad.getDeclaredMethod("main", String[].class);
            method.invoke(null, new Object[]{new String[0]});
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // Here is what I want to be called while loading all classes to replace string literals "Hi!" to "Hello!"
    // Next I also want to pass here class/method info (if possible) to specify the place of use of string literal in external application
    String InterceptClassLoaderStringLiteral(String literal){
        return literal.equals("Hi!") ? "Hello!" : literal;
    }
}

服务器应用程序(SomeApplication.jar):

package com.example.someapplication;

public class Main {
    public static void main(String[] args){
        System.out.println("I am SomeApplication: " + "Hi!");
        new SecondClass().printMe();
    }
}
package com.example.someapplication;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

public class SecondClass {
    void printMe() {
        System.out.println("I am SecondClass from SomeApplication: " + "Hi!");

        // Now call printMe from SomeChildApplication.jar
        File myJar = new File("SomeChildApplication.jar");
        try {
            URLClassLoader child = new URLClassLoader(new URL[]{myJar.toURI().toURL()});
            Class<?> classToLoad = Class.forName("com.example.somechildapplication.Main", true, child);
            Method method = classToLoad.getDeclaredMethod("printMe");
            Object instance = classToLoad.newInstance();
            method.invoke(instance);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

服务器应用程序使用的其他插件(SomeChildApplication.jar)

package com.example.somechildapplication;

public class Main {
    public void printMe(){
        System.out.println("I am SomeChildApplication: " + "Hi!");
    }
}

当我运行启动器时,控制台将打印:

  

我是MyLauncher
  我是SomeApplication:嗨!
  我是SomeApplication的SecondClass:您好!
  我是SomeChildApplication:您好!

我想打印它:

  

我是MyLauncher
  我是SomeApplication:您好!
  我是SomeApplication的SecondClass:您好!
  我是SomeChildApplication:您好!

因此,我想更改所有字符串文字“ Hi!”。向“你好!”在加载类时(即时)

有人有什么想法怎么做吗?
请不要将我发送到https://google.gik-team.com/?q=how+to+do+it之类的网址
我想给出代码示例的具体答案

谢谢=)

0 个答案:

没有答案