class 文件 JavaFX 中的魔法值不兼容
Incompatible magic value in class file JavaFX
我需要实现制表功能(使用 MenuItem TabulateFunction),该功能位于扩展名为 .class 的字节码形式的文件中。由于该函数可以具有实现我的接口的三个 class 之一,因此,根据任务,您需要实现一个单独的 class 来负责从文件并根据这个字节码创建一个对象。
我制作了一个 class ClassLoaderForFunctions 并在其中使用了 return defineClass
这就是问题所在。当我在菜单中 select 制表函数时,它会调用 ClassLoaderForFunctions 中的方法,该方法为文件中的函数实现上述内容。
当涉及到 return defineClass
时,我得到一个错误:线程异常 JavaFX Application Thread" java.lang.ClassFormatError: Incompatible magic value 11 in class file tlog/class
在 Main class 中,我调用控制器并将 tlog
对象的字节码写入扩展名为 .class
的文件中
*为了堆栈跟踪,我删除了导入行
可能是什么问题?
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:
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();
}
}
}
堆栈跟踪:
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(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(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(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(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:831)
您显然想做的是生成一个 .class
文件,然后您可以加载该文件。
但问题是您实际写入“tlog.class”的内容并不是标准的 class 文件格式。实际上,看起来您只是使用 DataOutputStream
方法编写了一堆数字。这甚至远不接近 valid1.
无论如何,当您随后尝试加载(假定的)class 文件时,JVM 实际上会说:
"Nah! That's not in a valid class file format. It doesn't even start with the correct magic number!"
那么解决方法是什么?
你可以(理论上)生成一个有效的 class 文件。问题是创建一个有效的 class 文件来实现您的功能将很困难,并且需要深入了解 Java 字节码和 class 文件的结构。并且不清楚你这样做是否会取得任何成就。
这里有几个(可能)更好的想法。
只是将数据作为数据文件进行读写。然后使用您从文件中读取的数据编写一些 Java 实现所需功能的代码。
编写一些 Java 代码以生成函数的 Java 源代码,将数据作为常量数组或其他内容嵌入文件中。然后调用Java编译器进行编译,加载生成的.class
文件。
第一个选项最简单,而且很可能满足您的所有需求。如果函数对性能至关重要,您 可能 考虑第二个选项。但是只有当您 测量了 性能时才应该这样做。此外,您可能会发现加速比很小,不值得为此付出 相当大 的努力。
1 - 格式记录在 JVM 规范的 Chapter 4 中。您需要了解更多规范才能为 classes 方法和伪方法编写字节码。
我需要实现制表功能(使用 MenuItem TabulateFunction),该功能位于扩展名为 .class 的字节码形式的文件中。由于该函数可以具有实现我的接口的三个 class 之一,因此,根据任务,您需要实现一个单独的 class 来负责从文件并根据这个字节码创建一个对象。
我制作了一个 class ClassLoaderForFunctions 并在其中使用了 return defineClass
这就是问题所在。当我在菜单中 select 制表函数时,它会调用 ClassLoaderForFunctions 中的方法,该方法为文件中的函数实现上述内容。
当涉及到 return defineClass
时,我得到一个错误:线程异常 JavaFX Application Thread" java.lang.ClassFormatError: Incompatible magic value 11 in class file tlog/class
在 Main class 中,我调用控制器并将 tlog
对象的字节码写入扩展名为 .class
*为了堆栈跟踪,我删除了导入行
可能是什么问题?
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:
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();
}
}
}
堆栈跟踪:
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(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(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(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(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:831)
您显然想做的是生成一个 .class
文件,然后您可以加载该文件。
但问题是您实际写入“tlog.class”的内容并不是标准的 class 文件格式。实际上,看起来您只是使用 DataOutputStream
方法编写了一堆数字。这甚至远不接近 valid1.
无论如何,当您随后尝试加载(假定的)class 文件时,JVM 实际上会说:
"Nah! That's not in a valid class file format. It doesn't even start with the correct magic number!"
那么解决方法是什么?
你可以(理论上)生成一个有效的 class 文件。问题是创建一个有效的 class 文件来实现您的功能将很困难,并且需要深入了解 Java 字节码和 class 文件的结构。并且不清楚你这样做是否会取得任何成就。
这里有几个(可能)更好的想法。
只是将数据作为数据文件进行读写。然后使用您从文件中读取的数据编写一些 Java 实现所需功能的代码。
编写一些 Java 代码以生成函数的 Java 源代码,将数据作为常量数组或其他内容嵌入文件中。然后调用Java编译器进行编译,加载生成的
.class
文件。
第一个选项最简单,而且很可能满足您的所有需求。如果函数对性能至关重要,您 可能 考虑第二个选项。但是只有当您 测量了 性能时才应该这样做。此外,您可能会发现加速比很小,不值得为此付出 相当大 的努力。
1 - 格式记录在 JVM 规范的 Chapter 4 中。您需要了解更多规范才能为 classes 方法和伪方法编写字节码。