I have written the following Reflection code:

static Class<?> craftWorld;
static Class<?> worldServer;
static Class<?> movingObjPosClass;
static Class<?> blockPosClass;
static Class<?> vec3DClass;
static Class<?> genAccessClass;
static Class<?> craftBlockClass;
static boolean use112 = false;

public GetTargetBlock113() {
    try {
        craftWorld = Class.forName("org.bukkit.craftbukkit." + Main.m.getServerVersion() + "CraftWorld");

        worldServer = Class.forName("net.minecraft.server." + Main.m.getServerVersion() + "WorldServer");
        movingObjPosClass = Class
                .forName("net.minecraft.server." + getServerVersion() + "MovingObjectPosition");
        blockPosClass = Class
                .forName("net.minecraft.server." + getServerVersion() + "BlockPosition");
        vec3DClass = Class.forName("net.minecraft.server." + Main.m.getServerVersion() + "Vec3D");
        try {
        genAccessClass = Class
                .forName("net.minecraft.server." + getServerVersion() + "GeneratorAccess");
        } catch (ClassNotFoundException e) {
            //Error is thrown if on older Minecraft versions
            //Ignore as error is expected.
        craftBlockClass = Class
                .forName("org.bukkit.craftbukkit." + Main.m.getServerVersion() + "block.CraftBlock");
    } catch (ClassNotFoundException e) {

public static Block getBlockLookingAt(Player player, int reach) {
    if (player == null) {
        throw new IllegalArgumentException("player cannot be null");
    if (reach < 1 || reach > 120) {
        throw new IllegalArgumentException("reach must be between 1-120");

    Location startLoc = player.getLocation().add(0, player.getEyeHeight(), 0);

    Vector start = startLoc.toVector();
    Vector direction = startLoc.getDirection().normalize().multiply(reach);
    Vector end = start.clone().add(direction);

    try {

        Constructor<?> con = vec3DClass.getConstructor(double.class, double.class, double.class);
        Object from = con.newInstance(start.getX(), start.getY(), start.getZ());
        Object to = con.newInstance(end.getX(), end.getY(), end.getZ());
        Object converted = craftWorld.cast(player.getWorld());
        Method handle = converted.getClass().getMethod("getHandle");
        Object worldServObj = handle.invoke(converted);
        Object convertedToWorldServer = worldServer.cast(worldServObj);

        Class<?>[] rayTraceArgs = new Class<?>[] { vec3DClass, vec3DClass };
        Method pingField = convertedToWorldServer.getClass().getMethod("rayTrace", rayTraceArgs);
        Object[] args = new Object[] { from, to };
        Object movingObjPos = pingField.invoke(worldServObj, args);
        if (movingObjPos == null) {
            return null;
        Method getBlockPos = movingObjPosClass.getMethod("a");
        Object blockPos = getBlockPos.invoke(movingObjPos);
        Block b;
        if (genAccessClass != null && !use112) {
        Class<?>[] worldPos = new Class<?>[] { genAccessClass, blockPosClass };
        Method blockAt = craftBlockClass.getMethod("at", worldPos);

        Object[] args2 = new Object[] { worldServObj, blockPos };
        b = (Block) blockAt.invoke(blockPos, args2);
        }else {
            Method getBlockPos1 = blockPosClass.getMethod("getX");
            Method getBlockPos2 = blockPosClass.getMethod("getY");
            Method getBlockPos3 = blockPosClass.getMethod("getZ"); 
            b = new Location(player.getWorld(), (int) getBlockPos1.invoke(blockPos), (int) getBlockPos2.invoke(blockPos), (int) getBlockPos3.invoke(blockPos)).getBlock();

        //System.out.println("Found block: " + b.getType());
        return b;
    } catch (NoSuchMethodException e) {
    } catch (SecurityException e) {
    } catch (IllegalAccessException e) {
    } catch (IllegalArgumentException e) {
    } catch (InvocationTargetException e) {
    } catch (InstantiationException e) {
    return null;

    /* WorldServer world = ((CraftWorld) player.getWorld()).getHandle();

     MovingObjectPosition rayTrace = world.rayTrace( new Vec3D(start.getX(),
     start.getY(), start.getZ()), new Vec3D(end.getX(), end.getY(), end.getZ()));
      BlockPosition pos = rayTrace.a(); 
      return rayTrace == null ? null :
     CraftBlock.at(world, pos);*/

The purpose of it is to get the target block in a Minecraft Bukkit plugin. It is necessary to do this with Reflection due to the varying class names of new versions, and the impossibility of importing them all.

However, this code is quite laggy.

How could the code to be optimised to be more efficient?

  • 1
    \$\begingroup\$ Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles. \$\endgroup\$ Oct 3, 2018 at 13:36
  • \$\begingroup\$ @TobySpeight I'm new to CodeReview, but what would be a proper title for this question? The title it's been edited to at the moment is pretty useless, as the question isn't even about Minecraft or Bukkit, but rather about Reflection. However, the way it's titled and tagged now implies an understanding of Minecraft is required, even though it is not. What title would be better? \$\endgroup\$
    – Joehot200
    Oct 3, 2018 at 17:42
  • 2
    \$\begingroup\$ I think the title is better than it was. The tags (more than the title) describe the technologies in use, so it's not necessary to repeat them in the title (most reviewers filter by the tags they are competent in, so that makes sense). Unfortunately, I haven't really written any Java for the last 15 years or so, otherwise I'd have a stab at reviewing it myself, and perhaps at enhancing the question some more. \$\endgroup\$ Oct 3, 2018 at 18:02
  • 1
    \$\begingroup\$ I 100% agree with @TobySpeight. The previous title was perfect but you've changed it to something unspecific that has no purpose and purposeless code is off-topic on Code Review \$\endgroup\$
    – t3chb0t
    Oct 4, 2018 at 7:54

1 Answer 1


The provided code sample is incomplete, so I don't know the control flow at runtime.
However, this is what I noticed:
The variables are static and so is getBlockLookingAt() method. However, the reflection code is done in the constructor of GetTargetBlock113 class. a more suitable place would be the static constructor of the class. depending on how many times the ctor is called, it might improve performance as well.

  • \$\begingroup\$ Please refrain from answering low-quality questions that are likely to get closed. Once, you've answered, that limits what can be done to improve the question, making it more likely that your efforts are wasted. It's better to wait until the question is properly ready before you answer! \$\endgroup\$ Oct 4, 2018 at 8:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.