Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.97a is out! (02/02/24); New blog post: Simulator Enhancements (03/13/24)

Author Topic: "Cannot determine simple type name <xyz>" Janino import resolving bugs  (Read 5159 times)

TJJ

  • Admiral
  • *****
  • Posts: 1905
    • View Profile

I don't ordinarily rely upon Janino for doing the compiling, but I used it for developing a little hack I've been playing with, and have come across rather major bugs in its parsing/resolving of imports.
It seems entirely random as to which imports it'll resolve correctly, and which it fails.

Take the below code for example (ignore its purpose, it's just to highlight Janino's import parsing bugs):

If I don't fully qualify "com.fs.starfarer.api.BaseModPlugin" or "java.lang.reflect.InvocationTargetException" (but instead import the classes), Janino will explode with the "Cannot determine simple type name ....".

If I change the code around a bit, new imports will begin failing.
It's completely infuriating, and basically leaves Janino not fit for purpose.

If I were a newbie programmer, this would be a huge roadblock, as Janino is barfing on 100% legal source.
Though perhaps the problem is less noticeable because newbie programmers won't be using an IDE, so won't have the imports auto-completed, and will instead be using wildcard * imports. (which probably avoids this bug?)


Code
package org.tjj.starsector;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.fs.starfarer.api.BaseModPlugin;
import com.fs.starfarer.api.Global;

public class IoTest extends com.fs.starfarer.api.BaseModPlugin {

private static Class fileIoClass;
private static Method readMethod;
private static Method writeMethod;

static {

byte[] fileIoClassBytes = new byte[] { -54, -2, -70, -66, 0, 0, 0, 50, 0, 49, 7, 0, 2, 1, 0, 29, 111, 114, 103,
47, 116, 106, 106, 47, 115, 116, 97, 114, 115, 101, 99, 116, 111, 114, 47, 70, 105, 108, 101, 73, 111,
73, 109, 112, 108, 7, 0, 4, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99,
116, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 10, 0, 3, 0,
9, 12, 0, 5, 0, 6, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0,
18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104,
105, 115, 1, 0, 31, 76, 111, 114, 103, 47, 116, 106, 106, 47, 115, 116, 97, 114, 115, 101, 99, 116, 111,
114, 47, 70, 105, 108, 101, 73, 111, 73, 109, 112, 108, 59, 1, 0, 4, 114, 101, 97, 100, 1, 0, 22, 40,
76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 91, 66, 7, 0, 17,
1, 0, 12, 106, 97, 118, 97, 47, 105, 111, 47, 70, 105, 108, 101, 10, 0, 16, 0, 19, 12, 0, 5, 0, 20, 1,
0, 21, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 86, 10,
0, 16, 0, 22, 12, 0, 23, 0, 24, 1, 0, 6, 116, 111, 80, 97, 116, 104, 1, 0, 22, 40, 41, 76, 106, 97, 118,
97, 47, 110, 105, 111, 47, 102, 105, 108, 101, 47, 80, 97, 116, 104, 59, 10, 0, 26, 0, 28, 7, 0, 27, 1,
0, 19, 106, 97, 118, 97, 47, 110, 105, 111, 47, 102, 105, 108, 101, 47, 70, 105, 108, 101, 115, 12, 0,
29, 0, 30, 1, 0, 12, 114, 101, 97, 100, 65, 108, 108, 66, 121, 116, 101, 115, 1, 0, 24, 40, 76, 106, 97,
118, 97, 47, 110, 105, 111, 47, 102, 105, 108, 101, 47, 80, 97, 116, 104, 59, 41, 91, 66, 7, 0, 32, 1,
0, 19, 106, 97, 118, 97, 47, 105, 111, 47, 73, 79, 69, 120, 99, 101, 112, 116, 105, 111, 110, 1, 0, 4,
112, 97, 116, 104, 1, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110,
103, 59, 1, 0, 1, 101, 1, 0, 21, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 79, 69, 120, 99, 101, 112,
116, 105, 111, 110, 59, 1, 0, 13, 83, 116, 97, 99, 107, 77, 97, 112, 84, 97, 98, 108, 101, 1, 0, 5, 119,
114, 105, 116, 101, 1, 0, 23, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105,
110, 103, 59, 91, 66, 41, 90, 7, 0, 41, 1, 0, 24, 106, 97, 118, 97, 47, 110, 105, 111, 47, 102, 105,
108, 101, 47, 79, 112, 101, 110, 79, 112, 116, 105, 111, 110, 10, 0, 26, 0, 43, 12, 0, 38, 0, 44, 1, 0,
71, 40, 76, 106, 97, 118, 97, 47, 110, 105, 111, 47, 102, 105, 108, 101, 47, 80, 97, 116, 104, 59, 91,
66, 91, 76, 106, 97, 118, 97, 47, 110, 105, 111, 47, 102, 105, 108, 101, 47, 79, 112, 101, 110, 79, 112,
116, 105, 111, 110, 59, 41, 76, 106, 97, 118, 97, 47, 110, 105, 111, 47, 102, 105, 108, 101, 47, 80, 97,
116, 104, 59, 1, 0, 1, 98, 1, 0, 2, 91, 66, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1,
0, 15, 70, 105, 108, 101, 73, 111, 73, 109, 112, 108, 46, 106, 97, 118, 97, 0, 33, 0, 1, 0, 3, 0, 0, 0,
0, 0, 3, 0, 1, 0, 5, 0, 6, 0, 1, 0, 7, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 8, -79, 0, 0, 0,
2, 0, 10, 0, 0, 0, 6, 0, 1, 0, 0, 0, 7, 0, 11, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 12, 0, 13, 0, 0, 0, 9,
0, 14, 0, 15, 0, 1, 0, 7, 0, 0, 0, 98, 0, 3, 0, 2, 0, 0, 0, 18, -69, 0, 16, 89, 42, -73, 0, 18, -74, 0,
21, -72, 0, 25, -80, 76, 1, -80, 0, 1, 0, 0, 0, 14, 0, 15, 0, 31, 0, 3, 0, 10, 0, 0, 0, 14, 0, 3, 0, 0,
0, 11, 0, 15, 0, 12, 0, 16, 0, 13, 0, 11, 0, 0, 0, 22, 0, 2, 0, 0, 0, 18, 0, 33, 0, 34, 0, 0, 0, 16, 0,
2, 0, 35, 0, 36, 0, 1, 0, 37, 0, 0, 0, 6, 0, 1, 79, 7, 0, 31, 0, 9, 0, 38, 0, 39, 0, 1, 0, 7, 0, 0, 0,
119, 0, 3, 0, 3, 0, 0, 0, 25, -69, 0, 16, 89, 42, -73, 0, 18, -74, 0, 21, 43, 3, -67, 0, 40, -72, 0, 42,
87, 4, -84, 77, 3, -84, 0, 1, 0, 0, 0, 20, 0, 22, 0, 31, 0, 3, 0, 10, 0, 0, 0, 18, 0, 4, 0, 0, 0, 19, 0,
20, 0, 20, 0, 22, 0, 21, 0, 23, 0, 22, 0, 11, 0, 0, 0, 32, 0, 3, 0, 0, 0, 25, 0, 33, 0, 34, 0, 0, 0, 0,
0, 25, 0, 45, 0, 46, 0, 1, 0, 23, 0, 2, 0, 35, 0, 36, 0, 2, 0, 37, 0, 0, 0, 6, 0, 1, 86, 7, 0, 31, 0, 1,
0, 47, 0, 0, 0, 2, 0, 48 };

ClassLoader cl = IoTest.class.getClassLoader();

Class clc = ClassLoader.class;

java.lang.reflect.Method defineClass;
try {
defineClass = clc.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Failed finding defineClass", e);
} catch (SecurityException e) {
throw new RuntimeException("Failed finding defineClass", e);
}

defineClass.setAccessible(true);

try {
fileIoClass = (Class) defineClass.invoke(cl.getParent().getParent(), "org.tjj.starsector.FileIoImpl",
fileIoClassBytes, 0, fileIoClassBytes.length);

} catch (IllegalAccessException e) {
throw new RuntimeException("Failed definingClass", e);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Failed definingClass", e);
} catch (java.lang.reflect.InvocationTargetException e) {
throw new RuntimeException("Failed definingClass", e);
}

try {
readMethod = fileIoClass.getDeclaredMethod("read", String.class);
writeMethod = fileIoClass.getDeclaredMethod("write", String.class, byte[].class);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Failed finding io methods", e);
} catch (SecurityException e) {
throw new RuntimeException("Failed finding io methods", e);
}
}

public static byte[] read(String path) {
try {
return (byte[]) readMethod.invoke(null, path);
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}

return null;
}

public static boolean write(String path, byte[] b) {
try {
return (Boolean) writeMethod.invoke(null, path, b);
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}

return false;
}

public IoTest() {
if (write("Test.txt", "Yep, Sandbox bypassed".getBytes())) {
Global.getLogger(IoTest.class).info("Successfully written file");
}
}

}
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23986
    • View Profile

Yeah, Janino has a bunch of bugs. Part of the reason I've moved away from it almost entirely; but it's still good to have to lower the barrier of entry to modding certain things. As you say, for this particular one, it's not super likely to come up.

(Also, apparently the sandboxing has bugs/holes as well. It's a cool hack - but, fair warning: I'll be fixing that.)
Logged

Dark.Revenant

  • Admiral
  • *****
  • Posts: 2806
    • View Profile
    • Sc2Mafia

It may be helpful, then, to offer the ability to write arbitrary ascii files.  That cannot be abused, except to fill up a hard drive with continuous writes.
Logged

TJJ

  • Admiral
  • *****
  • Posts: 1905
    • View Profile

Is there a reason for not using Java's embedded compiler?
Is the compilation time significantly longer than Janino?
« Last Edit: April 13, 2016, 10:30:20 AM by TJJ »
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23986
    • View Profile

Is there a reason for not using Java's embedded compiler?
Is the compilation time significantly longer than Janino?

IIRC that requires shipping with the JDK instead of the JRE. Which, aside from being bigger, may also be against the Java license - don't remember exactly, been a long time since I looked at it.
Logged

SolTech

  • Ensign
  • *
  • Posts: 2
    • View Profile
Re: "Cannot determine simple type name <xyz>" Janino import resolving bugs
« Reply #5 on: September 24, 2017, 04:26:29 AM »

I appear to be getting the same problem with Xanderzoo's missionmaker

So I've recently got missionmaker, only problem is when I export a mission (in my case straight into the ingame missions folder), add its name to the mission_list.csv, when I load the game with said mission, I get greeted by this:

Fatal: Error compiling [data.missions.afflictorbattletest.MissionDefinition]
Cause: File 'data/missions/afflictorbattletest/MissionDefinition.java' Line 14
Collumn 42: Cannot determine simple type name "MissionDefinitionPlugin"
Check starsector.log for more info

So, any help would be appreciated!
Logged