I'm trying to link my Android app with a JAR that was compiled with Free Pascal. I'm getting the following build error:
[2012-09-14 16:08:38 - MyApp] Dx
EXCEPTION FROM SIMULATION:
[2012-09-14 16:08:38 - MyApp] Dx local 0009: invalid
[2012-09-14 16:08:38 - Yarxi] Dx ...at bytecode offset 00015f2c
locals[0000]: Lcom/mypackage/$Core$$_fpc_nestedvars$70;
locals[0001]: I
locals[0002]: I
locals[0003]: I
locals[0004]: I
locals[0005]: I
locals[0006]: I
locals[0007]: I
locals[0008]: I
locals[0009]: <invalid>
locals[000a]: <invalid>
(..more locals... much more)
locals[06db]: <invalid>
stack[0003]: I
stack[0002]: I
stack[0001]: [I
stack[top0]: int{0x00000000 / 0}
...while working on block 5f23
...while working on method $MyMethod$944$FPR1:(Lcom/mypackage/$Core$$_fpc_nestedvars$70;)V
...while processing $MyMethod$944$FPR1 (Lcom/mypackage/$Core$$_fpc_nestedvars$70;)V
...while processing com/mypackage/Core.class
[2012-09-14 16:08:40 - MyApp] Dx 1 error; aborting
[2012-09-14 16:08:40 - MyApp] Conversion to Dalvik format failed with error 1
The error seems to be that at some point, the code tries to read local 0009, which is not initialized.
Now, Pascal does not enforce initialization of local variables. Chances are, initialization was omitted in the first place. I've retained the JVM assembly file that Free Pascal generated for me. Those are assembled with Jasmin into class files. The file is huge - I'm not pasting it here.
Can someone please help me trace back the point of error to the source? The error is at bytecode offset 00015f2c. Is there a way to translate that back into assembly file line number?
Resolved. 00015f2c (89900 decimal) is, indeed, a bytecode offset within a method. I did the following.
First, I called Jasmin directly, passing the generated .j file and the -g option (generate line numbers):
java -jar %JASM% -g Core.j
Free Pascal does not emit -g by itself. This gave me an alternative Core.class file with line numbers in it, line numbers being relative to the FPC-generated .j file. Then I used javap to disassemble the class back into another .j file:
"%JDKROOT%\javap" -l -c Core.class >Core_WithLines.j
But this new .j file contained line numbers and offsets of each individual command. I then searched for offset 89900 in the offending method (note: offsets, as generated by javap, wrap at 65536). Then I looked at the LineNumberTable below that method's body (both offsets and line numbers wrap), found the line number in the source Core.j file that corresponded to this offset. Looked back at Core.j, and there was a comment that contained the line number of the Pascal source.
There was, indeed, a function call that passed an uninitialized variable - but as a var parameter.
The issue is something of a Pascal/JVM borderline issue. The variable was uninitialized, but it was passed by ref into a function to be returned from the latter. The compiler should've abstracted that away somehow, IMHO, but FPC did not.
Related
I am attempting to simply compile a helloworld scala file from within a directory named using unicode characters but the scala compiler fails to run. It succeeds when I change directory's out the unicode named folder.
Detail
Given a classic Helloworld.scala class such as the one below
that is located in the directory:
/Users/me/Dev/Company/𝔘𝔫𝔦𝔠𝔬𝔡𝔢/code_folder
I am unable to run scalac on the code if my current directory is in code_folder which is the root directory for the Helloworld.scala. When I change directories out of the folder with the unicode name /𝔘𝔫𝔦𝔠𝔬𝔡𝔢, the compiler works just fine on the same code. So it would seem that scalac doesnt work when attempting to compile code while in a folder with unicode characters.
Why is that? Is this a system error? An unparsed unicode error between the OS starting the scalac process?
object Main{
def main(args: Array[String]): Unit = {
println("Hello world")
}
}
I expected a compiled file. The error I get is this
Exception in thread "main" java.lang.ExceptionInInitializerError
at scala.tools.util.PathResolver$Environment$.scalaExtDirs(PathResolver.scala:77)
at scala.tools.util.PathResolver$Defaults$.scalaExtDirs(PathResolver.scala:127)
at scala.tools.nsc.settings.StandardScalaSettings.$init$(StandardScalaSettings.scala:31)
at scala.tools.nsc.settings.MutableSettings.<init>(MutableSettings.scala:28)
at scala.tools.nsc.Settings.<init>(Settings.scala:19)
at scala.tools.nsc.Driver.process(Driver.scala:53)
at scala.tools.nsc.Driver.main(Driver.scala:80)
at scala.tools.nsc.Main.main(Main.scala)
Caused by: java.lang.IllegalArgumentException: Error decoding percent encoded characters
at java.base/sun.net.www.ParseUtil.decode(ParseUtil.java:209)
at java.base/jdk.internal.loader.FileURLMapper.getPath(FileURLMapper.java:64)
at java.base/jdk.internal.loader.FileURLMapper.exists(FileURLMapper.java:73)
at java.base/jdk.internal.loader.URLClassPath$JarLoader.getJarFile(URLClassPath.java:802)
at java.base/jdk.internal.loader.URLClassPath$JarLoader.access$900(URLClassPath.java:692)
at java.base/jdk.internal.loader.URLClassPath$JarLoader$1.run(URLClassPath.java:751)
at java.base/jdk.internal.loader.URLClassPath$JarLoader$1.run(URLClassPath.java:744)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/jdk.internal.loader.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:743)
at java.base/jdk.internal.loader.URLClassPath$JarLoader.<init>(URLClassPath.java:718)
at java.base/jdk.internal.loader.URLClassPath$3.run(URLClassPath.java:486)
at java.base/jdk.internal.loader.URLClassPath$3.run(URLClassPath.java:469)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/jdk.internal.loader.URLClassPath.getLoader(URLClassPath.java:468)
at java.base/jdk.internal.loader.URLClassPath.getLoader(URLClassPath.java:437)
at java.base/jdk.internal.loader.URLClassPath.findResource(URLClassPath.java:280)
at java.base/jdk.internal.loader.BuiltinClassLoader.findResourceOnClassPath(BuiltinClassLoader.java:479)
at java.base/jdk.internal.loader.BuiltinClassLoader.findResource(BuiltinClassLoader.java:303)
at java.base/java.lang.ClassLoader.getResource(ClassLoader.java:1393)
at java.base/java.lang.ClassLoader.getSystemResource(ClassLoader.java:1658)
at java.base/java.lang.ClassLoader.getSystemResourceAsStream(ClassLoader.java:1762)
at java.base/java.lang.Class.getResourceAsStream(Class.java:2607)
at scala.util.PropertiesTrait.scalaProps(Properties.scala:39)
at scala.util.PropertiesTrait.scalaProps$(Properties.scala:37)
at scala.tools.reflect.WrappedProperties$AccessControl$.scalaProps$lzycompute(WrappedProperties.scala:49)
at scala.tools.reflect.WrappedProperties$AccessControl$.scalaProps(WrappedProperties.scala:49)
at scala.util.PropertiesTrait.scalaPropOrNone(Properties.scala:71)
at scala.util.PropertiesTrait.scalaPropOrNone$(Properties.scala:71)
at scala.tools.reflect.WrappedProperties$AccessControl$.scalaPropOrNone(WrappedProperties.scala:49)
at scala.util.PropertiesTrait.$init$(Properties.scala:83)
at scala.tools.reflect.WrappedProperties$AccessControl$.<init>(WrappedProperties.scala:49)
at scala.tools.reflect.WrappedProperties$AccessControl$.<clinit>(WrappedProperties.scala)
... 8 more
Version:
scalac -version
Scala compiler version 2.12.8 -- Copyright 2002-2018, LAMP/EPFL and Lightbend, Inc.
MacOS version 10.13.6
Not really a solution, but some piece of information:
I set up my folder this way:
/home/nicolas/Private/𝔘𝔫𝔦𝔠𝔬𝔡𝔢/
When the ClassLoader tries to load the classes of your project it makes a list of paths where to lookup classes as a list of URLClassPath
Now when the code goes on and it tries to parse these paths, it calls sun.net.www.ParseUtil.decode()
When I put a breakpoint in here, I can see that the path for our class is:
/home/nicolas/Private/%ed%a0%b5%ed%b4%98%ed%a0%b5%ed%b4%ab%ed%a0%b5%ed%b4%a6%ed%a0%b5%ed%b4%a0%ed%a0%b5%ed%b4%ac%ed%a0%b5%ed%b4%a1%ed%a0%b5%ed%b4%a2/target/scala-2.12/classes/
so it somehow translated 𝔘𝔫𝔦𝔠𝔬𝔡𝔢 into a percent encoded string : %ed%a0%b5%ed%b4%98%ed%a0%b5%ed%b4%ab%ed%a0%b5%ed%b4%a6%ed%a0%b5%ed%b4%a0%ed%a0%b5%ed%b4%ac%ed%a0%b5%ed%b4%a1%ed%a0%b5%ed%b4%a2
This in turn creates a CharsetDecoder for UTF-8:
CharsetDecoder dec = ThreadLocalCoders.decoderFor("UTF-8")
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
and tries to decode the above url but it fails and that is why the classes can't be loaded.
Now if I go here https://www.branah.com/unicode-converter and tries to convert 𝔘𝔫𝔦𝔠𝔬𝔡𝔢 to a % encoded string, it gives me
%f0%9d%94%98%f0%9d%94%ab%f0%9d%94%a6%f0%9d%94%a0%f0%9d%94%ac%f0%9d%94%a1%f0%9d%94%a2
And if when I debug, I change the url using this encoded string value, ie
/home/nicolas/Private/%f0%9d%94%98%f0%9d%94%ab%f0%9d%94%a6%f0%9d%94%a0%f0%9d%94%ac%f0%9d%94%a1%f0%9d%94%a2/target/scala-2.12/classes/
Then it parses it properly and keeps going.
So I don't know where it gets that %ed%a0%b5%ed%b4%98%ed%a0%b5%ed%b4%ab%ed%a0%b5%ed%b4%a6%ed%a0%b5%ed%b4%a0%ed%a0%b5%ed%b4%ac%ed%a0%b5%ed%b4%a1%ed%a0%b5%ed%b4%a2
The interesting thing is that if I use the same website and try to convert back %ed%a0%b5%ed%b4%98%ed%a0%b5%ed%b4%ab%ed%a0%b5%ed%b4%a6%ed%a0%b5%ed%b4%a0%ed%a0%b5%ed%b4%ac%ed%a0%b5%ed%b4%a1%ed%a0%b5%ed%b4%a2 then I also get 𝔘𝔫𝔦𝔠𝔬𝔡𝔢
So I am a bit confused
I am trying to run an implementation a jason code that is using some Internal Actions. The interpreter is showing that it was not possible to find the "java" code of the internal action, as showed:
Server running on http://191.36.8.42:3272
[aslparser] [peleus.asl:29] warning: The internal action class for 'org.soton.peleus.act.plan(Goals)' was not loaded! Error:
java.lang.ClassNotFoundException: org.soton.peleus.act.plan
[aslparser] [peleus.asl:42] warning: The internal action class for 'org.soton.peleus.act.isTrue(H)' was not loaded! Error:
java.lang.ClassNotFoundException: org.soton.peleus.act.isTrue
[peleus] Could not finish intention: intention 1: +des([on(b3,table),on(b2,b3),on(b1,b2)])[source(self)] <- ... org.soton.peleus.act.plan(Goals); !checkGoals(Goals); .print("Goals ",Goals," were satisfied") /
{Goals=[on(b3,table),on(b2,b3),on(b1,b2)]}Trigger: +des([on(b3,table),on(b2,b3),on(b1,b2)])[noenv,code(org.soton.peleus.act.plan([on(b3,table),on(b2,b3),on(b1,b2)])),code_line(29),code_src("peleus.asl"),error(action_failed),error_msg("no environment configured!"),source(self)]
[peleus] Adding belief clear(table)
This mas2j file is as following:
MAS peleus {
infrastructure: Centralised
agents:
peleus;
}
Part of agent code (written by Felipe Meneguzzi) is showed bellow:
//The next line is line 28
+des(Goals) : true
<- org.soton.peleus.act.plan(Goals);
!checkGoals(Goals);
.print("Goals ",Goals," were satisfied").
+!checkGoals([]) : true <- true.
//The next line is line 40
+!checkGoals([H|T]) : true
<- .print("Checking ", H);
org.soton.peleus.act.isTrue(H);
!checkGoals(T).
I guess it is about the folder structure, how to set up Jason to search for java files in specific locations?
The folders structure is like this:
Peleus\src\org\soton\peleus for java files
Peleus\examples for mas2j and asl tested project
It all depends on how you are executing the application.
If you are using java, the CLASSPATH should be defined to include the missing classes.
if you are using jason script (that uses Ant), the .mas2j file should include the class path as well.
More on that in the FAQ. Notice that CLASSPATH is where .class files are found, not .java source code files. The error regards a missing class, not a missing source code.
This question is kind of similar to Q1 and Q2.
My Java code, which uses JNA to load a native library, goes like this:
69. Print.good("found file: " + libraryPath);
70. if( System.getProperty("os.name").toLowerCase().contains("win") ) {
71. final String search_path = FileFinder.getParentDirPath(libraryPath);
72. NativeLibrary.addSearchPath("libReliableServerNative",
73. search_path );
74. Print.good("Added search path: " + search_path);
75. System.setProperty("java.library.path", search_path);
76. nativeLib = (NativeLib) Native.loadLibrary("libReliableServerNative", CTest.class);
}
My terminal output, which prints the line number and library file location, goes like this:
++ Thread "main": Core_Reliable.Stupid_Client_UDP_Reliable.<clinit>(Stupid_Client_UDP_Reliable.java:69)
++ found file: C:\Users\HOLLYWOOD\Documents\NetBeansProjects\ReliableServerMadeUnreliable2\build\classes\libReliableServerNative.dll
++ Thread "main": Core_Reliable.Stupid_Client_UDP_Reliable.<clinit>(Stupid_Client_UDP_Reliable.java:74)
++ Added search path: C:\Users\HOLLYWOOD\Documents\NetBeansProjects\ReliableServerMadeUnreliable2\build\classes
java.lang.UnsatisfiedLinkError: The specified module could not be found.
at com.sun.jna.Native.open(Native Method)
at com.sun.jna.Native.open(Native.java:1759)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:260)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Library$Handler.<init>(Library.java:147)
at com.sun.jna.Native.loadLibrary(Native.java:412)
at com.sun.jna.Native.loadLibrary(Native.java:391)
at Core_Reliable.Stupid_Client_UDP_Reliable.<clinit>(Stupid_Client_UDP_Reliable.java:76)
Exception in thread "main" Java Result: 1
^ You see that on line 76 in my Java code, Native.loadLibrary throws an UnsatisfiedLinkError. ^
I ruled out the possibility that I was mixing up 32 bit and 64 bit libraries because I compiled the native library and the Java code on a 32 bit Windows machine with 32 bit Java, and specified the "-m32" command line parameter for gcc, which should output a 32 bit dll. For native compilation, I used cygwin.
I also ruled out the possibility that the library could not be found because when that was the case I got "java.lang.UnsatisfiedLinkError: Unable to load library" instead of the above "java.lang.UnsatisfiedLinkError: The specified module could not be found."
I think that what is going on is "that it could not be loaded... that the dll was missing some dependencies." But the native library (libReliableServerNative.dll) is nothing more than a single C file with no dependencies other than the C standard library.
Full dependencies for libReliableServerNative:
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h> // inet_aton
#include<sys/socket.h> // unix socket
#include <unistd.h>
#include <netinet/in.h>
Do you have any idea why this is happening?
* Update *
The Unsatisfied Link Error went away when I put cygwin1.dll in the jna path.
My problem now is that I am not getting any error messages. The native method never gets called - no printf statements from the native code appear, but the program doesn't terminate or throw any exceptions. The java statements after the call to nativeLib.myFunction() don't get executed.
I got it working. If you compile with cygwin, you have to put cygwin1.dll in the resource path.
Platform: Windows 7 x64
JDK version: 7.0.25 x64 or 7.0.45 x64
JDK installation path:
C:\Java\jdk725 or default c:\Program Files\Java\jdk1.7.0_25\
Spring Framework Release: 3.2.4 or 3.2.5
UAC: enabled or disabled
gradlew build (after gradlew):
:referenceHtmlMulti FAILED
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':referenceHtmlMulti'.
Failed to compile stylesheet. 59 errors detected.
Try:
Run with --info or --debug option to get more log output.
Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':referen
ceHtmlMulti'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecuteActions(ExecuteActionsTaskExecuter.java:69)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecute(ExecuteActionsTaskExecuter.java:46)
..
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:130)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:48)
Caused by: javax.xml.transform.TransformerConfigurationException: Failed to comp
ile stylesheet. 59 errors detected.
at com.icl.saxon.PreparedStyleSheet.prepare(PreparedStyleSheet.java:136)
at com.icl.saxon.TransformerFactoryImpl.newTemplates(TransformerFactoryI
mpl.java:127)
at com.icl.saxon.TransformerFactoryImpl.newTransformer(TransformerFactor
yImpl.java:79)
..
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecuteAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecuteActions(ExecuteActionsTaskExecuter.java:61)
... 70 more
BUILD FAILED
My question is: why did my build fail?
The problem happens when :referenceHtmlMulti task is executing.
If we look in groovy class we will see that XSLT transformation is used to create docbook-reference. Despite the fact, that Saxon is used (TransformerFactoryImpl is selected) the choosen SAXParserFactory is org.apache.xerces.jaxp.SAXParserFactoryImpl (I wonder why not to use com.icl.saxon.aelfred.SAXParserFactoryImpl).
IF we look what implementation of xerces is used by gradle we will see xercesImpl-2.9.1.jar, which is old enough.
Now let's find class URI in xerces sources. It represents a Uniform Resource Identifier (URI). On line 1134 we can find
else if (!isURICharacter(testChar)) {
throw new MalformedURIException(
"Opaque part contains invalid character: " + testChar);
}
Now let's look how this function works:
private static boolean isURICharacter (char p_char) {
return (p_char <= '~' && (fgLookupTable[p_char] & MASK_URI_CHARACTER) != 0);
}
We can see that function will return true if char comparision will return true also. But that means rather close limits of chars (from code 0 - 126 (~)). But what about non US-ASCII character set?
Let's read RFC 2396 about non us-ascii characters (that can exist in your windows path, representing your local language or can be found in account name, under which gradle unpacks itself and works): other catagory - The Unicode characters that are not in the US-ASCII character set, are not control characters (according to the Character.isISOControl method), and are not space characters (according to the Character.isSpaceChar method) (Deviation from RFC 2396, which is limited to US-ASCII). The set of all legal URI characters consists of the unreserved, reserved, escaped, and other characters.
So. URI identification fails. And that is the place where build code fails.
There are 2 solutions:
To make your account name or path consist only of US-ASCII characters.
To patch URI class (for example, by rewriting function isURICharacter)
I want to call CRF++ toolkit from a java program. I type the following:
Process process = runtime.exec("/home/toshiba/Bureau/CRF++-0.54/.libs/lt-crf_learn /home/toshiba/Bureau/CRF++-0.54/example/atb/template /home/toshiba/Bureau/CRF++-0.54/example/atb/tr_java.data");
process.waitFor();
But, I have the the following error:
CRF++: Yet Another CRF Tool Kit
Copyright (C) 2005-2009 Taku Kudo, All rights reserved.
Usage: /home/toshiba/Bureau/CRF++-0.54/.libs/lt-crf_learn [options] files
-f, --freq=INT use features that occuer no less than INT(default 1)
-m, --maxiter=INT set INT for max iterations in LBFGS routine(default 10k)
-c, --cost=FLOAT set FLOAT for cost parameter(default 1.0)
-e, --eta=FLOAT set FLOAT for termination criterion(default 0.0001)
-C, --convert convert text model to binary model
-t, --textmodel build also text model file for debugging
-a, --algorithm=(CRF|MIRA) select training algorithm
-p, --thread=INT number of threads(default 1)
-H, --shrinking-size=INT set INT for number of iterations variable needs to be optimal before considered for shrinking. (default 20)
-v, --version show the version and exit
-h, --help show this help and exit
I 'm wondering if any one could help me?
I don't think that's a bug in CRF++, since you are able to run it from command line. So the actual question is how to pass arguments properly when starting a process using Runtime.exec(). I would suggest trying the following:
String[] cmd = {"/home/toshiba/Bureau/CRF++-0.54/.libs/lt-crf_learn",
"/home/toshiba/Bureau/CRF++-0.54/example/atb/template",
"/home/toshiba/Bureau/CRF++-0.54/example/atb/tr_java.data"};
Process p = Runtime.getRuntime().exec(cmd);
This may help since Runtime.exec() sometimes splits the command line into arguments in a rather strange fashion.
Another potential problem is mentioned here: Java Runtime.exec()
There's a simple solution for this. Just write your command into a temporary file and execute that file as Runtime.getRuntime.exec("sh <temp-filename>"). Later you can delete this file. I will explain reason behind this if this solution works for you.