2016-02-19 2 views
0

Я обрабатываю байт-код в java, но выполняется во внешнем, запущенном JAR-файле. По этой причине я использую API-интерфейс attach.Attach library DLL не может быть загружена приложением

Моя текущая проблема заключается в том, что API-интерфейс attach не может загрузить DLL, имеющуюся у меня в отдельной папке. У меня были проблемы с расположением файлов, но я исправил их, поэтому я знаю, что он может видеть файл, он просто не может его загрузить.

Мой трассировки стека выглядит следующим образом:

java.lang.UnsatisfiedLinkError: Can't load library: C:\Users\Jamie\Desktop\Test Rainbow 51\Rainbow Tester\plugins_mod\Natives\64\windows\attach.dll 
    at java.lang.ClassLoader.loadLibrary(Unknown Source) 
    at java.lang.Runtime.load0(Unknown Source) 
    at java.lang.System.load(Unknown Source) 
    at RainbowBans.MyPlugin.getAttachProvider(MyPlugin.java:299) 
    at RainbowBans.MyPlugin.onStartup(MyPlugin.java:96) 
    at joebkt._JoeUtils.LoadPlugins(_JoeUtils.java:2415) 
    at joebkt._JoeUtils.Startup(_JoeUtils.java:2502) 
    at joebkt.DedicatedServer.startServerConsoleHandler(DedicatedServer.java:44) 
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:483) 
    at java.lang.Thread.run(Unknown Source) 

А вот мой исходный код:

package RainbowBans; 

//Just a few imports 
import java.awt.Desktop; 
import java.awt.event.*; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
//Required when used to start premain by command line. 
//import java.lang.ProcessBuilder.Redirect; 
import java.net.Socket; 
import java.net.SocketAddress; 
import java.net.URL; 
import java.util.Timer; 
import java.util.TimerTask; 

import javax.swing.*; 

import sun.tools.attach.BsdAttachProvider; 
import sun.tools.attach.LinuxAttachProvider; 
import sun.tools.attach.SolarisAttachProvider; 
import sun.tools.attach.WindowsAttachProvider; 
import net.minecraft.server.MinecraftServer; 

import com.mojang.authlib.GameProfile; 
import com.sun.tools.attach.AgentInitializationException; 
import com.sun.tools.attach.AgentLoadException; 
import com.sun.tools.attach.AttachNotSupportedException; 
import com.sun.tools.attach.VirtualMachine; 
import com.sun.tools.attach.spi.AttachProvider; 

import joebkt.BannedPlayers; 
import joebkt.CmdBan; 
import joebkt.CmdKick; 
import joebkt.PlayerList; 
import joebkt._PermMgr; 
import PluginReference.*; 

public class MyPlugin extends PluginBase{ 

public static MC_Server server = null; 
String pluginDir = "plugins_mod" + File.separatorChar; 
String folderDir = pluginDir + "RainbowBans" + File.separatorChar; 
String rainbowDir = RainbowBans.MyPlugin.class.getProtectionDomain().getCodeSource().getLocation().toExternalForm(); 
String OS = "Unknown!"; 

public void onStartup(MC_Server svr){ 
    System.out.println("Plugin starting! Lets hope this works! :)"); 
    System.out.println("plugins_mod folder located at:" + new File(pluginDir).getAbsolutePath()); 
    System.out.println("RainbowBansTransAgent is located at: " + new File(pluginDir + "RainbowBansTransAgent.jar").getAbsolutePath()); 
    server = svr; 
    System.out.println("Creating files now!"); 
    File file = new File(folderDir); 
    if(file.isDirectory()) System.out.println("Directory already exists!"); 
    else { 
     System.out.println("Creating plugin directory"); 
     file.mkdir(); 
    } 
    File errorfile = new File(folderDir + File.separatorChar +  "Rainbowbanserrors.txt"); 
    if(errorfile.isFile()) System.out.println("File errorfile already exists"); 
    else 
     try { 
      System.out.println("Creating stack trace file!"); 
      errorfile.createNewFile(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    File banfile = new File(folderDir + File.separatorChar + "banmessage.txt"); 
    if(banfile.isFile()) System.out.println("Banfile already exists!"); 
    else 
     try { 
      banfile.createNewFile(); 
      BufferedWriter writer = new BufferedWriter(new FileWriter(banfile)); 
      writer.write("You are banned."); 
      writer.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    File logfile = new File(folderDir + File.separatorChar + "Rainbowbanstransagentlog.txt"); 
    if(logfile.isFile()) System.out.println("Logfile already exists!"); 
    else try{ 
     logfile.createNewFile(); 
    }catch(IOException e){ 
    e.printStackTrace(); 
    } 
    JFrame frame = startDialog(); 
    JMenuBar menu = createMenu(); 
    frame.setJMenuBar(menu); 
    VirtualMachine vm; 
    try { 

     AttachProvider.setAttachProvider(getAttachProvider()); 
     vm = VirtualMachine.attach(String.valueOf(Thread.currentThread().getId())); 
     String realArch = architecture(); 
     if(realArch == "64"){ 
      System.setProperty("java.library.path", new File(folderDir + "Natives" + File.separator + "64" + File.separator + OS + File.separator).getAbsolutePath()); 
     }else if(realArch == "32"){ 
      System.setProperty("java.library.path", new File(folderDir + "Natives" + File.separator + "32" + File.separator + OS + File.separator).getAbsolutePath()); 
     } 

      vm.loadAgent(new File(".").getAbsolutePath()); 
    } catch (AttachNotSupportedException | IOException | AgentLoadException | AgentInitializationException e) { 
     e.printStackTrace(); 
    } 
    //Before using the attach agent, this is how I started the premain in the external JAR (RainbowBansTransAgent.jar)// 
    /*File transagent = new File(pluginDir + File.separatorChar + "RainbowBansTransAgent.jar"); 
    ProcessBuilder pb = new ProcessBuilder("java", "-javaagent:" + transagent.getAbsolutePath(), "RainbowBansTransAgent/TransAgent"); 
    pb.redirectError(Redirect.appendTo(errorfile)); 
    pb.redirectOutput(Redirect.appendTo(logfile)); 
    try{ 
     pb.start(); 
    }catch(IOException e){ 
     e.printStackTrace(); 
    } 
    */ 
} 

private JMenuBar createMenu() { 
    JMenuBar menu = new JMenuBar(); 
    JMenuItem i = new JMenuItem("See message"); 
    i.addActionListener(getActionListenerForMessage(i)); 
    menu.add(i); 
    JMenuItem w = new JMenuItem("Go to project page"); 
    w.addActionListener(getActionListenerForWebsites("http://www.project- rainbow.org/site/index.php?board=9.0")); 
    menu.add(w); 
    JMenuItem k = new JMenuItem("Go to download page"); 
    k.addActionListener(getActionListenerForWebsites("http://www.project- rainbow.org/site/index.php?action=downloads;cat=3")); 
    menu.add(k); 
    return menu;  
} 
//I got the code from http://stackoverflow.com/questions/10967451/open-a-link-in-browser-with-java-button 
private void openWebsite(String url){ 
    Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; 
    if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) { 
     try { 
      desktop.browse(new URL(url).toURI()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
private ActionListener getActionListenerForWebsites(String url) { 
    ActionListener al = new ActionListener(){ 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      openWebsite(url); 
     } 

    }; 
    return al; 
} 
private ActionListener getActionListenerForMessage(JMenuItem i) { 
    ActionListener al = new ActionListener(){ 
     @Override 
     public void actionPerformed(ActionEvent e) { 
       try { 
        BufferedReader reader = new BufferedReader(new FileReader(new File(folderDir + File.separatorChar + "banmessage.txt"))); 
        String message = reader.readLine(); 
        i.setText(message); 
        Timer timer = new Timer(); 
        timer.schedule(getTimerTask(i), 5000); 
        reader.close(); 
       } catch (IOException e1) { 
        e1.printStackTrace(); 
       } 
      } 

    }; 
    return al; 
} 
private TimerTask getTimerTask(JMenuItem i) { 
    TimerTask task = new TimerTask(){ 
     @Override 
     public void run() { 
      i.setText("See message"); 
     } 
    }; 
    return task; 
} 
private JFrame startDialog() { 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JOptionPane.YES_NO_OPTION); 
    frame.setVisible(true); 
    frame.setSize(800, 600); 
    frame.setAlwaysOnTop(false); 
    frame.setBackground(java.awt.Color.yellow); 
    return frame; 
} 
//Copied from CodeCrafter's MultiWorld project. 
private AttachProvider getAttachProvider() { 
    String os = System.getProperty("os.name").toLowerCase(); 
    if (os.contains("win") && !os.contains("darwin")) { 
     OS = "windows"; 
     if(architecture() == "64")System.load(new File(pluginDir + "Natives" + File.separator + "64" + File.separator + "windows" + File.separator + "attach.dll").getAbsolutePath()); 
     else if (architecture() == "32")System.load(new File(pluginDir + "Natives" + File.separator + "32" + File.separator + "windows" + File.separator + "attach.dll").getAbsolutePath()); 
     else{} 
     return new WindowsAttachProvider(); 
    } 
    else if ((os.contains("nix")) || (os.contains("nux")) || (os.indexOf("aix") > 0)) { 
     OS = "linux"; 
     if(architecture() == "64")System.load(new File(pluginDir + "Natives" + File.separator + "64" + File.separator + "linux" + File.separator + "libattach.so").getAbsolutePath()); 
     else if(architecture() == "32") System.load(new File(pluginDir + "Natives" + File.separator + "64" + File.separator + "linux" + File.separator + "libattach.so").getAbsolutePath()); 
     else{} 
    return new LinuxAttachProvider(); 
    } 
    else if (os.contains("mac")) { 
     OS = "mac"; 
     System.load(new File(pluginDir + "Natives" + File.separator + "64" + File.separator + "mac" + File.separator + "libattach.dylib").getAbsolutePath()); 
     return new BsdAttachProvider(); 
    } 
    else if (os.contains("sunos")) { 
     OS = "solaris"; 
     if(architecture() == "64")System.load(new File(pluginDir + "Natives" + File.separator + "64" + File.separator + "solaris" + File.separator + "libattach.so").getAbsolutePath()); 
     else if(architecture() == "32")System.load(new File(pluginDir + "Natives" + File.separator + "64" + File.separator + "solaris" + File.separator + "libattach.so").getAbsolutePath()); 
    return new SolarisAttachProvider(); 
    } 
    else{ 
     return null; 
    } 
} 
//Copied from StackOverflow 
private String architecture() { 
    String arch = System.getenv("PROCESSOR_ARCHITECTURE"); 
    String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432"); 

    String realArch = arch.endsWith("64") 
        || wow64Arch != null && wow64Arch.endsWith("64") 
         ? "64" : "32"; 
    return realArch; 
} 
} 
+1

Вы можете изучить зависимости DLL от Dependeny Walker: http://www.dependencywalker.com/depends22_x64.zip –

ответ

0

Оказывается, моя проблема в том, что я не добавлял свою DLL в Java. library.path. Задача решена.

Смежные вопросы