我需要實作 tabulate 函式(使用 MenuItem TabulateFunction),它以位元組碼的形式位于一個擴展名為 .class 的檔案中。由于函式可以擁有實作我的介面的三個類之一,那么,根據任務,您需要實作一個單獨的類,該類將負責從檔案中讀取位元組碼并基于該位元組創建一個物件-代碼。
我創建了一個 ClassLoaderForFunctions 類并return defineClass在其中使用,這就是問題所在。當我在選單中選擇 Tabulate Function 時,它會呼叫 ClassLoaderForFunctions 中的方法,該方法為檔案中的函式實作了上述內容。
當涉及到時return defineClass,我收到一個錯誤:執行緒中的例外JavaFX Application Thread" java.lang.ClassFormatError: Incompatible magic value 11 in class file tlog/class
在 Main 類中,我呼叫控制器并將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();
}
}
表格函式檔案:
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$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)
uj5u.com熱心網友回復:
您顯然想要做的是生成一個.class檔案,然后您可以加載該檔案。
但問題是您實際寫入“tlog.class”的內容不是標準類檔案格式。實際上,看起來您只是在使用DataOutputStream方法撰寫一堆數字。這甚至遠不接近有效的1。
無論如何,當您嘗試加載(假設的)類檔案時,JVM 會說,實際上:
“不!那不是有效的類檔案格式。它甚至沒有以正確的幻數開頭!”
那么解決方案是什么?
那么你可以(理論上)生成一個有效的類檔案。問題是創建一個有效的類檔案來實作你的函式會很困難,并且需要深入了解 Java 位元組碼和類檔案的結構。并且不清楚您是否會通過這樣做來實作任何目標。
這里有幾個(可能)更好的想法。
只需將資料作為資料檔案讀取和寫入即可。然后使用從檔案中讀取的資料撰寫一些實作所需功能的 Java 代碼。
撰寫一些 Java 代碼來為函式生成 Java 源代碼,將資料作為常量陣列或其他內容嵌入檔案中。然后呼叫Java編譯器進行編譯,并加載生成的
.class檔案。
第一個選項是最簡單的,而且很可能是您需要的所有選項。如果該功能對性能至關重要,您可能會考慮第二個選項。但是,只有在測量了性能后才應該這樣做。此外,您可能會發現加速比很小,并且不值得為實作它而付出相當大的努力。
1 - 該格式記錄在JVM 規范的第 4 章中。您需要了解更多規范才能撰寫類方法和偽方法的位元組碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/361196.html
