简体   繁体   English

class 文件 JavaFX 中不兼容的魔法值

[英]Incompatible magic value in class file JavaFX

I need to implement the tabulate function (using MenuItem TabulateFunction), which is located in a file with the extension.class in the form of byte-code.我需要实现表格function(使用MenuItem TabulateFunction),它位于一个以字节码形式扩展名为class的文件中。 Since the function can have one of the three classes that implement my interface, then, according to the task, you need to implement a separate class that will be responsible for reading the byte-code from the file and create an object based on this byte-code.由于 function 可以具有实现我的接口的三个类之一,那么,根据任务,您需要实现一个单独的 class ,它将负责从文件中读取字节码并创建一个 ZA8CFDE6331BD59EB2AC96F8 上-代码。

I made a class ClassLoaderForFunctions and use return defineClass in it And here is the problem.我做了一个 class ClassLoaderForFunctions 并在其中使用return defineClass这就是问题所在。 When I select Tabulate Function in my menu, it calls the method from ClassLoaderForFunctions which implements the above for the function from the file.当我 select 在我的菜单中列出 Function 时,它会调用 ClassLoaderForFunctions 中的方法,该方法为文件中的 function 实现上述方法。

And when it comes to return defineClass , I get an error: Exception in thread JavaFX Application Thread" java.lang.ClassFormatError: Incompatible magic value 11 in class file tlog/classreturn defineClass时,我得到一个错误: Exception in thread JavaFX Application Thread" java.lang.ClassFormatError: Incompatible magic value 11 in class file tlog/class

In the Main class I call the controller and write the byte code of the tlog object in a file with the extension.class在主 class 中,我调用 controller 并将 tlog object 的字节码写入扩展名为tlog的文件中。

*I deleted the import lines for the sake of Stack Trace *为了堆栈跟踪,我删除了导入行

What could be the problem?可能是什么问题呢?

ClassLoaderForFunctions:类加载器函数:

package JavaFX_Application;

public class ClassLoaderForFunctions extends ClassLoader{

    public Class<?> loadClassFromFile(File file) throws IOException {
    FileInputStream in = new FileInputStream(file);
    byte[] fileContent = new byte[in.available()]; //available - возвращает количество байтов ввода, доступные в данный момент для чтения
    in.read(fileContent);
    in.close();

    return defineClass(file.getName(), fileContent, 0, fileContent.length);
}

}

FXMLMainFormController: FXMLMainForm控制器:

        package JavaFX_Application;

   


    public class FXMLMainFormController implements Initializable {

        public static TabulatedFunctionDoc tabFDoc = new TabulatedFunctionDoc();
        private Stage MainStage;
        private File file;
        private ClassLoaderForFunctions Loader;
        private FXMLMenuController ctrl;
        private Alert dialog;

        @FXML
        private MenuItem TabulateFunction;

        @FXML
        private MenuItem NewFunction;
    
        @FXML
        private MenuItem FileClose;

        @FXML
        private MenuItem OpenFile;

        @FXML
        private MenuItem SaveFile;

        @FXML
        private MenuItem SaveFileAs;

        @FXML
        private TableView<FunctionPointT> table = new TableView<>();

        @FXML
        private Label point_count;

        @FXML
        private TextField edX = new TextField(),edY = new TextField();

        @FXML
        private TableColumn<FunctionPointT,Double> columnX = new         TableColumn<FunctionPointT,Double>("X");;

        @FXML
        private TableColumn<FunctionPointT,Double> columnY = new         TableColumn<FunctionPointT,Double>("Y");;

        @FXML
        private void deletePoint(ActionEvent event) throws IOException {
            if (isSelected()) {
                tabFDoc.deletePoint(getIndex() - 1);
            } else {
                if(tabFDoc.getPointsCount() > 2)
                    tabFDoc.deletePoint(tabFDoc.getPointsCount() - 1);
                else
                    showDialog("Length of Document < 3","Please add some point or stop         trying to delete point");

            }
        }

        @FXML
        private void addPoint(ActionEvent event) throws         InappropriateFunctionPointException, IOException {
            if(!edX.getText().isEmpty() && !edY.getText().isEmpty()) {
                tabFDoc.addPoint(new FunctionPoint(Double.parseDouble(edX.getText()),         Double.parseDouble(edY.getText())));
            }
            edX.setText("");
            edY.setText("");
            //table.getItems().add(new         FunctionPointT(Double.parseDouble(edX.getText()),Double.parseDouble(edY.getText()))); //         добавляем строку
        }

        @FXML
        public void redraw(){
            if(!table.getColumns().isEmpty())
                table.getItems().clear();
            ObservableList<FunctionPointT> data = table.getItems();
            for(int i = 0;i< tabFDoc.getPointsCount(); ++ i) {
                data.add(new         FunctionPointT(tabFDoc.getLink().getPointX(i),tabFDoc.getLink().getPointY(i)));
            }
            if (isSelected()) {
                point_count.setText("Point " + getIndex() + " of " + tabFDoc.getPointsCount());
            } else {
                point_count.setText("Point " + tabFDoc.getPointsCount() + " of " +         tabFDoc.getPointsCount());
            }
        }

        @FXML
        private void setSelectedIndexByKey(){
            point_count.setText("Point " + getIndex() + " of " +         tabFDoc.getPointsCount());
        }

        @FXML
        private void setSelectedIndexByClick() {
            if(isSelected() && tabFDoc !=null)
                point_count.setText("Point " + getIndex() + " of " +         tabFDoc.getPointsCount());
        }

        private void openWindow() throws IOException {
            Stage primaryStage = new Stage();
            FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLMenu.fxml"));
            Parent root = loader.load();
            ctrl = loader.getController();
            ctrl.setMainController(this);

            primaryStage.setTitle("Create New Function");
            primaryStage.setScene(new Scene(root));
            primaryStage.setResizable(false);

            primaryStage.initModality(Modality.APPLICATION_MODAL);
            primaryStage.initOwner(MainStage);
            primaryStage.setOnCloseRequest(windowEvent -> {
                windowEvent.consume();
            });
            primaryStage.showAndWait();
        }

        private void SaveFunctionAs() throws IOException {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("Open file");
            fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Text         files", "*.json"));
            file = fileChooser.showSaveDialog(table.getScene().getWindow());
            if(file!=null) {
                tabFDoc.saveFunctionAs(file.getName());
            }
        }

        @Override
        public void initialize(URL url, ResourceBundle resourceBundle) {
            dialog = new Alert(Alert.AlertType.ERROR);
            tabFDoc.setController(this);
            columnX.setCellValueFactory(new PropertyValueFactory<FunctionPointT,Double>        ("X"));
            table.getColumns().add(columnX);
            columnY.setCellValueFactory(new PropertyValueFactory<FunctionPointT,Double>        ("Y"));
            table.getColumns().add(columnY);
            table.setPrefWidth(573.0);
            table.setPrefHeight(220.0);
            columnY.setPrefWidth(286.5);
            columnX.setPrefWidth(286.5);
            Loader = new ClassLoaderForFunctions();
            ObservableList<FunctionPointT> data = table.getItems();
            for(int i = 0;i< tabFDoc.getPointsCount(); ++ i) {
                data.add(new         FunctionPointT(tabFDoc.getLink().getPointX(i),tabFDoc.getLink().getPointY(i)));
            }

            NewFunction.setOnAction(event -> {
                try {
                    openWindow();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            OpenFile.setOnAction(event ->{
                FileChooser fileChooser = new FileChooser();
                fileChooser.setTitle("Open file");
                fileChooser.getExtensionFilters().add(new         FileChooser.ExtensionFilter("Text files", "*.json"));
                file = fileChooser.showOpenDialog(table.getScene().getWindow());
                if(file!=null) {
                    tabFDoc.loadFunction(file.getName());
                    redraw();
                }
            });
            FileClose.setOnAction(event ->{
                MainStage.close();
            });
            SaveFile.setOnAction(event ->{
                try {
                    tabFDoc.saveFunction();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            SaveFileAs.setOnAction(event -> {
                try {
                    SaveFunctionAs();
                } catch (IOException e) {
                   e.printStackTrace();
                }
            });
            TabulateFunction.setOnAction(event->{
                try {
                    FileChooser fileChooser = new FileChooser();
                    fileChooser.setTitle("Open class");
                    fileChooser.getExtensionFilters().add(new         FileChooser.ExtensionFilter("Class files", "*.class"));
                    file = fileChooser.showOpenDialog(table.getScene().getWindow());
                    //tabFDoc.setFunction((Function)         Loader.loadClassFromFile(file).getConstructor().newInstance());
                    if (file != null) {
                        openWindow();
                        if(ctrl.getLeftDomainBorderBorder() != Double.POSITIVE_INFINITY         && ctrl.getRightDomainBorderBorder() != Double.NEGATIVE_INFINITY && ctrl.getPointsCount() >         2) {
                            tabFDoc.tabulateFunction((Function)         Loader.loadClassFromFile(file).getConstructor().newInstance(),         ctrl.getLeftDomainBorderBorder(), ctrl.getRightDomainBorderBorder(), ctrl.getPointsCount());
                            redraw();
                        }
                    }
                }
                catch (Exception e) {
                }
            });


        }

        public boolean isSelected(){
            return (table.getSelectionModel().getSelectedItem() != null);
        }

        private int getIndex(){
            int index = 0;
            if (isSelected()) {
                for (int i = 0; i < tabFDoc.getPointsCount(); ++i) {
                    if (table.getSelectionModel().getSelectedItem().getX() ==         tabFDoc.getLink().getPointX(i) && table.getSelectionModel().getSelectedItem().getY() ==         tabFDoc.getLink().getPointY(i))
                        index = i + 1;
                }
            }
            return index++;
        }

        public void setStage(Stage stage){
            MainStage = stage;
        }

        public Stage getStage(){
            return MainStage;
        }

        public TabulatedFunctionDoc getTabFDoc(){
            return tabFDoc;
        }

        public void showDialog(String header, String message) {

            dialog.setHeaderText(header);
            dialog.setTitle("Error");
            dialog.setContentText(message);
            dialog.showAndWait();

        }

    }

TabulatedFunctionDoc:制表函数文档:

package JavaFX_Application;

import functions.*;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class TabulatedFunctionDoc implements TabulatedFunction {
    private TabulatedFunction Link;
    private String fileName = "";
    private boolean modified = false;
    private boolean fileNameAssigned = false;
    private FXMLMainFormController controller;
    private Function function = null;


    public TabulatedFunctionDoc() {
        Link = new ArrayTabulatedFunction(-1, 1, 2);
    }

    public void setFunction(Function input_function){
        function = input_function;
    }

public void setController(FXMLMainFormController ctrl) {
    this.controller = ctrl;
}

public void CallRedraw() throws IOException {
    if(registerRedrawFunctionController(controller))
        controller.redraw();
}

public TabulatedFunction getLink() {
    return Link;
}

public boolean registerRedrawFunctionController(FXMLMainFormController ctrl) {
    return ctrl.getStage().isShowing();
}

public boolean isModified() {
    return modified;
}

public boolean isFileNameAssigned() {
    return fileNameAssigned;
}

public void newFunction(double leftX, double rightX, int pointsCount) throws IOException {
    Link = new ArrayTabulatedFunction(leftX, rightX, pointsCount);
    modified = false;
}

public void tabulateFunction(Function function, double leftX, double rightX, int pointsCount) {
    Link = TabulatedFunctions.tabulate(function, leftX, rightX, pointsCount);
    modified = false;
}

public void saveFunctionAs(String fileName) throws IOException {
    this.fileName = fileName;
    fileNameAssigned = true;
    saveFunction();
    modified = false;
}

public void loadFunction(String fileName) {
    this.fileName = fileName;
    fileNameAssigned = true;

    JSONParser jsonParser = new JSONParser();

    try (FileReader reader = new FileReader(fileName))
    {
        Object obj = jsonParser.parse(reader);
        JSONArray employeeList = (JSONArray) obj;
        FunctionPoint[] array = new FunctionPoint[employeeList.size()];
        //System.out.println(employeeList);
        for(int i = 0; i < employeeList.size(); ++ i){

            JSONObject employeeObject = (JSONObject)((JSONObject)employeeList.get(i)).get("Точки");

            array[i] = new FunctionPoint((Double) employeeObject.get("X"),(Double) employeeObject.get("Y"));
        }
        this.Link = new ArrayTabulatedFunction(array);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ParseException e) {
        e.printStackTrace();
    }
    modified = false;
}

public void saveFunction() throws IOException {

    JSONArray Link = new JSONArray();

    for(int i =0; i < this.Link.getPointsCount(); ++i){
        JSONObject point = new JSONObject();
        point.put("X",this.Link.getPointX(i));
        point.put("Y",this.Link.getPointY(i));
        JSONObject points = new JSONObject();
        points.put("Точки",point);
        Link.add(points);
    }
    FileWriter fileWriter = new FileWriter(fileName);
    fileWriter.write(Link.toJSONString());
    fileWriter.flush();
    modified = false;

}

@Override
public int getPointsCount() {
    return this.Link.getPointsCount();
}

@Override
public void setPointY(int index, double y) throws IOException {
    this.Link.setPointY(index, y);
    this.modified = true;
    CallRedraw();
}

@Override
public double getPointY(int index) {
    return this.Link.getPointY(index);
}

@Override
public double getPointX(int index) {
    return this.Link.getPointX(index);
}

@Override
public double getFunctionValue(double x) {
    return this.Link.getFunctionValue(x);
}

@Override
public void addPoint(FunctionPoint point) throws InappropriateFunctionPointException, IOException {
    this.modified = true;
    this.Link.addPoint(point);
    CallRedraw();
}

@Override
public void setPoint(int index, FunctionPoint point) throws InappropriateFunctionPointException, IOException {
    this.Link.setPoint(index, point);
    this.modified = true;
    CallRedraw();
}

@Override
public void setPointX(int index, double x) throws InappropriateFunctionPointException, IOException {
    this.Link.setPointX(index, x);
    this.modified = true;
    CallRedraw();
}

@Override
public void deletePoint(int index) throws IOException {
    this.Link.deletePoint(index);
    this.modified = true;
    CallRedraw();
}

@Override
public double getRightDomainBorder() {
    return this.Link.getRightDomainBorder();
}

@Override
public double getLeftDomainBorder() {
    return this.Link.getLeftDomainBorder();
}

@Override
public FunctionPoint getPoint(int index) {
    if (index >= 0 && index < this.getPointsCount()) {
        return new FunctionPoint(this.Link.getPoint(index));
    } else {
        throw new FunctionPointIndexOutOfBoundsException();
    }
}
}

Stack Trace:堆栈跟踪:

Exception in thread "JavaFX Application Thread" java.lang.ClassFormatError: Incompatible magic value 11 in class file tlog/class
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1010)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:872)
    at JavaFX_Application.ClassLoaderForFunctions.loadClassFromFile(ClassLoaderForFunctions.java:15)
    at JavaFX_Application.FXMLMainFormController.lambda$initialize$6(FXMLMainFormController.java:206)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.controls/javafx.scene.control.MenuItem.fire(MenuItem.java:459)
    at javafx.controls/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1385)
    at javafx.controls/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1338)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1878)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:557)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:943)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:831)

What you are apparently trying to do is generate a .class file that you can then load.您显然想要做的是生成一个.class文件,然后您可以加载该文件。

But the problem is that what you are actually writing to "tlog.class" is not in the standard class file format.但问题是您实际写入“tlog.class”的内容不是标准的 class 文件格式。 In fact, it looks like you are just writing a bunch of numbers using DataOutputStream methods.事实上,看起来您只是在使用DataOutputStream方法编写一堆数字。 That isn't even remotely close to valid 1 .这甚至远不接近有效1

At any rate, when you then attempt to load the (supposed) class file, the JVM is saying, in effect:无论如何,当您尝试加载(假定的)class 文件时,JVM 实际上是在说:

"Nah. That's not in a valid class file format. It doesn't even start with the correct magic number!" “不。那不是有效的 class 文件格式。它甚至没有以正确的幻数开头!”

So what is the solution?那么解决方案是什么?

Well you could (in theory) generate a valid class file.那么你可以(理论上)生成一个有效的 class 文件。 The problem is that creating a valid class file that implements your function is going to be difficult, and require deep knowledge of Java bytecodes and the structure of class files. The problem is that creating a valid class file that implements your function is going to be difficult, and require deep knowledge of Java bytecodes and the structure of class files. And it is not clear that you are going to achieve anything by doing that.并且不清楚你是否会通过这样做来实现任何目标。

Here are a couple of (probably) better ideas.这里有几个(可能)更好的想法。

  1. Just read and write the data as a data file.只需将数据作为数据文件读取和写入。 Then write some Java code that implements the required function, using the data that you read from the file.然后使用从文件中读取的数据编写一些实现所需 function 的 Java 代码。

  2. Write some Java code to generate Java source code for the function, embedding the data in the file as arrays of constants or whatever. Write some Java code to generate Java source code for the function, embedding the data in the file as arrays of constants or whatever. Then call the Java compiler to compile it, and load the resulting .class file.然后调用Java编译器编译,加载生成的.class文件。

The first option is the simplest, and most likely all that you need.第一个选项是最简单的,而且很可能满足您的所有需求。 You might consider the second option if the function was performance critical.如果 function 对性能至关重要,您可能会考虑第二个选项。 But you should only do that if you have measured the performance.但是,只有在您测量了性能后,您才应该这样做。 Besides, you will probably find the the speedup will be small, and not worth the considerable effort needed to achieve it.此外,您可能会发现加速效果很小,不值得为此付出大量努力。


1 - The format is documented inChapter 4 of the JVM specification. 1 - 格式记录在 JVM 规范的第 4 章中。 You will need to understand a lot more of the spec in order to write the bytecodes for the classes methods and pseudo-methods.您需要了解更多规范才能为类方法和伪方法编写字节码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM