{"id":15132599,"url":"https://github.com/readytalk/avian","last_synced_at":"2025-05-16T02:07:11.779Z","repository":{"id":3194720,"uuid":"4227709","full_name":"ReadyTalk/avian","owner":"ReadyTalk","description":"[INACTIVE] Avian is a lightweight virtual machine and class library designed to provide a useful subset of Java's features, suitable for building self-contained applications.","archived":false,"fork":false,"pushed_at":"2021-02-19T02:20:09.000Z","size":20491,"stargazers_count":1225,"open_issues_count":38,"forks_count":173,"subscribers_count":94,"default_branch":"master","last_synced_at":"2025-05-16T02:06:27.500Z","etag":null,"topics":["java","jit-compiler","jvm","openjdk","portable"],"latest_commit_sha":null,"homepage":"https://readytalk.github.io/avian/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ReadyTalk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-05-04T18:18:55.000Z","updated_at":"2025-05-09T05:35:18.000Z","dependencies_parsed_at":"2022-08-26T08:00:06.497Z","dependency_job_id":null,"html_url":"https://github.com/ReadyTalk/avian","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReadyTalk%2Favian","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReadyTalk%2Favian/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReadyTalk%2Favian/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReadyTalk%2Favian/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ReadyTalk","download_url":"https://codeload.github.com/ReadyTalk/avian/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453652,"owners_count":22073617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","jit-compiler","jvm","openjdk","portable"],"created_at":"2024-09-26T04:21:32.224Z","updated_at":"2025-05-16T02:07:11.749Z","avatar_url":"https://github.com/ReadyTalk.png","language":"C++","readme":"Avian - A lightweight Java Virtual Machine (JVM)\n================================================\n\n**PLEASE NOTE: This project is not currently being developed, maintained, or supported.  Feel free to use and/or fork it, but any issues filed here will probably be ignored.**\n\n[![Build Status](https://travis-ci.org/ReadyTalk/avian.png?branch=master)](https://travis-ci.org/ReadyTalk/avian)\n\nQuick Start\n-----------\n\nThese are examples of building Avian on various operating systems for\nthe x86_64 architecture.  You may need to modify JAVA_HOME according\nto where the JDK is installed on your system.  In all cases, be sure\nto use forward slashes in the path.\n\n#### on Linux:\n    $ export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64\n    $ make\n    $ build/linux-x86_64/avian -cp build/linux-x86_64/test Hello\n\n#### on Mac OS X:\n    $ export JAVA_HOME=$(/usr/libexec/java_home)\n    $ make\n    $ build/macosx-x86_64/avian -cp build/macosx-x86_64/test Hello\n\n#### on Windows (Cygwin):\n    $ git clone git@github.com:ReadyTalk/win64.git ../win64\n    $ export JAVA_HOME=\"/cygdrive/c/Program Files/Java/jdk1.7.0_45\"\n    $ make\n    $ build/windows-x86_64/avian -cp build/windows-x86_64/test Hello\n\n#### on FreeBSD:\n    $ export JAVA_HOME=/usr/local/openjdk7\n    $ gmake\n    $ build/freebsd-x86_64/avian -cp build/freebsd-x86_64/test Hello\n\n\nIntroduction\n------------\n\nAvian is a lightweight virtual machine and class library designed to\nprovide a useful subset of Java's features, suitable for building\nself-contained applications.\n\n\nSupported Platforms\n-------------------\n\nAvian can currently target the following platforms:\n\n  * Linux (i386, x86_64, ARM, and ARM64)\n  * Windows (i386 and x86_64)\n  * Mac OS X (i386 and x86_64)\n  * Apple iOS (i386, x86_64, ARM, and ARM64)\n  * FreeBSD (i386, x86_64)\n\n\nBuilding\n--------\n\nBuild requirements include:\n\n  * GNU make 3.80 or later\n  * GCC 4.6 or later\n      or LLVM Clang 3.1 or later (see use-clang option below)\n  * JDK 1.6 or later\n  * MinGW 3.4 or later (only if compiling for Windows)\n  * zlib 1.2.3 or later\n\nEarlier versions of some of these packages may also work but have not\nbeen tested.\n\nThe build is directed by a single makefile and may be influenced via\ncertain flags described below, all of which are optional.\n\n    $ make \\\n        platform={linux,windows,macosx,ios,freebsd} \\\n        arch={i386,x86_64,arm,arm64} \\\n        process={compile,interpret} \\\n        mode={debug,debug-fast,fast,small} \\\n        lzma=\u003clzma source directory\u003e \\\n        bootimage={true,false} \\\n        tails={true,false} \\\n        continuations={true,false} \\\n        use-clang={true,false} \\\n        openjdk=\u003copenjdk installation directory\u003e \\\n        openjdk-src=\u003copenjdk source directory\u003e \\\n        android=\u003candroid source directory\u003e \\\n        ios-version=\u003ciOS minimum version\u003e\n\n  * `platform` - the target platform\n    * _default:_ output of $(uname -s | tr [:upper:] [:lower:]),\nnormalized in some cases (e.g. CYGWIN_NT-5.1 -\u003e windows)\n\n  * `arch` - the target architecture\n    * _default:_ output of $(uname -m), normalized in some cases\n(e.g. i686 -\u003e i386)\n\n  * `process` - choice between pure interpreter or JIT compiler\n    * _default:_ compile\n\n  * `mode` - which set of compilation flags to use to determine\noptimization level, debug symbols, and whether to enable\nassertions\n    * _default:_ fast\n\n  * `lzma` - if set, support use of LZMA to compress embedded JARs and\nboot images.  The value of this option should be a directory\ncontaining a recent LZMA SDK (available [here](http://www.7-zip.org/sdk.html)).  Currently, only version 9.20 of\nthe SDK has been tested, but other versions might work.\n    * _default:_ not set\n\n  * `armv6` - if true, don't use any instructions newer than armv6.  By\ndefault, we assume the target is armv7 or later, and thus requires explicit\nmemory barrier instructions to ensure cache coherency\n\n  * `bootimage` - if true, create a boot image containing the pre-parsed\nclass library and ahead-of-time compiled methods.  This option is\nonly valid for process=compile builds.  Note that you may need to\nspecify both build-arch=x86_64 and arch=x86_64 on 64-bit systems\nwhere \"uname -m\" prints \"i386\".\n    * _default:_ false\n\n  * `tails` - if true, optimize each tail call by replacing the caller's\nstack frame with the callee's.  This convention ensures proper\ntail recursion, suitable for languages such as Scheme.  This\noption is only valid for process=compile builds.\n    * _default:_ false\n\n  * `continuations` - if true, support continuations via the\navian.Continuations methods callWithCurrentContinuation and\ndynamicWind.  See Continuations.java for details.  This option is\nonly valid for process=compile builds.\n    * _default:_ false\n\n  * `use-clang` - if true, use LLVM's clang instead of GCC to build.\nNote that this does not currently affect cross compiles, only\nnative builds.\n    * _default:_ false\n\n  * `openjdk` - if set, use the OpenJDK class library instead of the\ndefault Avian class library.  See \"Building with the OpenJDK Class\nLibrary\" below for details.\n    * _default:_ not set\n\n  * `openjdk-src` - if this and the openjdk option above are both set,\nbuild an embeddable VM using the OpenJDK class library.  The JNI\ncomponents of the OpenJDK class library will be built from the\nsources found under the specified directory.  See \"Building with\nthe OpenJDK Class Library\" below for details.\n    * _default:_ not set\n\n  * `android` - if set, use the Android class library instead of the\ndefault Avian class library.  See \"Building with the Android Class\nLibrary\" below for details.\n    * _default:_ not set\n\n  * `ios-version` - the minimum iOS SDK version which will be used\nwhen compiling for ios target. Do not use a value 11.0 or larger,\nif you want to support 32 bit version. This option is only valid\nfor platform=ios .\n    * _default:_ 8.0\n\nThese flags determine the name of the directory used for the build.\nThe name always starts with _${platform}-${arch}_, and each non-default\nbuild option is appended to the name.  For example, a debug build with\nbootimage enabled on Linux/x86_64 would be built in\n_build/linux-x86_64-debug-bootimage_.  This allows you to build with\nseveral different sets of options independently and even\nsimultaneously without doing a clean build each time.\n\nNote that not all combinations of these flags are valid.  For instance,\nnon-jailbroken iOS devices do not allow JIT compilation, so only\nprocess=interpret or bootimage=true builds will run on such\ndevices.  See [here](https://github.com/ReadyTalk/hello-ios) for an\nexample of an Xcode project for iOS which uses Avian.\n\nIf you are compiling for Windows, you may either cross-compile using\nMinGW or build natively on Windows under Cygwin.\n\n#### Installing Cygwin:\n\n  __1.__ Download and run setup.exe from [cygwin's website](http://www.cygwin.com), installing the base\n  system and these packages: make, gcc-mingw-g++,\n  mingw64-i686-gcc-g++, mingw64-x86_64-gcc-g++, and (optionally) git.\n\nYou may also find our win32 repository useful: (run this from the\ndirectory containing the avian directory)\n\n    $ git clone git@github.com:ReadyTalk/win32.git\n\nThis gives you the Windows JNI headers, zlib headers and library, and\na few other useful libraries like OpenSSL, libjpeg, and libpng.\nThere's also a win64 repository for 64-bit builds:\n\n      $ git clone git@github.com:ReadyTalk/win64.git\n\n\nBuilding with the Microsoft Visual C++ Compiler\n-----------------------------------------------\n\nYou can also build using the MSVC compiler, which makes debugging with\ntools like WinDbg and Visual Studio much easier.  Note that you will\nstill need to have GCC installed - MSVC is only used to compile the\nC++ portions of the VM, while the assembly code and helper tools are\nbuilt using GCC.\n\n*Note that the MSVC build isn't tested regularly, so is fairly likely to be broken.*\n\nAvian targets MSVC 11 and above (it uses c++ features not available in older versions).\n\nTo build with MSVC, install Cygwin as described above and set the\nfollowing environment variables:\n\n    $ export PATH=\"/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/Common7/IDE:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC/BIN:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/Common7/Tools:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v3.5:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC/VCPackages:/cygdrive/c/Program Files/Microsoft SDKs/Windows/v6.0A/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem\"\n    $ export LIBPATH=\"C:\\WINDOWS\\Microsoft.NET\\Framework\\v3.5;C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727;C:\\Program Files\\Microsoft Visual Studio 11.0\\VC\\LIB;\"\n    $ export VCINSTALLDIR=\"C:\\Program Files\\Microsoft Visual Studio 11.0\\VC\"\n    $ export LIB=\"C:\\Program Files\\Microsoft Visual Studio 11.0\\VC\\LIB;C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A\\lib;\"\n    $ export INCLUDE=\"C:\\Program Files\\Microsoft Visual Studio 11.0\\VC\\INCLUDE;C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A\\include;\"\n\nAdjust these definitions as necessary according to your MSVC\ninstallation.\n\nFinally, build with the msvc flag set to the MSVC tool directory:\n\n    $ make msvc=\"/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC\"\n\n\nBuilding with the OpenJDK Class Library\n---------------------------------------\n\nBy default, Avian uses its own lightweight class library.  However,\nthat library only contains a relatively small subset of the classes\nand methods included in the JRE.  If your application requires\nfeatures beyond that subset, you may want to tell Avian to use\nOpenJDK's class library instead.  To do so, specify the directory\nwhere OpenJDK is installed, e.g.:\n\n    $ make openjdk=/usr/lib/jvm/java-7-openjdk\n\nThis will build Avian as a conventional JVM (e.g. libjvm.so) which\nloads its boot class library and native libraries (e.g. libjava.so)\nfrom _/usr/lib/jvm/java-7-openjdk/jre_ at runtime.  Note that you must\nuse an absolute path here, or else the result will not work when run\nfrom other directories.  In this configuration, OpenJDK needs to\nremain installed for Avian to work, and you can run applications like\nthis:\n\n    $ build/linux-x86_64-openjdk/avian-dynamic -cp /path/to/my/application \\\n        com.example.MyApplication\n\nAlternatively, you can enable a stand-alone build using OpenJDK by\nspecifying the location of the OpenJDK source code, e.g.:\n\n    $ make openjdk=$(pwd)/../jdk7/build/linux-amd64/j2sdk-image \\\n        openjdk-src=$(pwd)/../jdk7/jdk/src\n\nYou must ensure that the path specified for openjdk-src does not have\nany spaces in it; make gets confused when dependency paths include\nspaces, and we haven't found away around that except to avoid paths\nwith spaces entirely.\n\nThe result of such a build is a self-contained binary which does not\ndepend on external libraries, jars, or other files.  In this case, the\nspecified paths are used only at build time; anything needed at\nruntime is embedded in the binary.  Thus, the process of running an\napplication is simplified:\n\n    $ build/linux-x86_64-openjdk-src/avian -cp /path/to/my/application \\\n        com.example.MyApplication\n\nNote that the resulting binary will be very large due to the size of\nOpenJDK's class library.  This can be mitigated using UPX, preferably\nan LZMA-enabled version:\n\n    $ upx --lzma --best build/linux-x86_64-openjdk-src/avian\n\nYou can reduce the size futher for embedded builds by using ProGuard\nand the supplied openjdk.pro configuration file (see \"Embedding with\nProGuard and a Boot Image\" below).  Note that you'll still need to use\nvm.pro in that case -- openjdk.pro just adds additional constraints\nspecific to the OpenJDK port.  Also see\n[app.mk](https://github.com/ReadyTalk/avian-swt-examples/blob/master/app.mk)\nin the _avian-swt-examples_ project for an example of using Avian,\nOpenJDK, ProGuard, and UPX in concert.\n\nHere are some examples of how to install OpenJDK and build Avian with\nit on various OSes:\n\n#### Debian-based Linux:\n_Conventional build:_\n\n    $ apt-get install openjdk-7-jdk\n    $ make openjdk=/usr/lib/jvm/java-7-openjdk test\n\n_Stand-alone build:_\n\n    $ apt-get install openjdk-7-jdk\n    $ apt-get source openjdk-7-jdk\n    $ apt-get build-dep openjdk-7-jdk\n    $ (cd openjdk-7-7~b147-2.0 \u0026\u0026 dpkg-buildpackage)\n    $ make openjdk=/usr/lib/jvm/java-7-openjdk \\\n        openjdk-src=$(pwd)/openjdk-7-7~b147-2.0/build/openjdk/jdk/src \\\n        test\n\n#### Mac OS X:\n_Prerequisite:_ Build OpenJDK 7 according to [this site](https://wikis.oracle.com/display/OpenJDK/Mac+OS+X+Port).\n\n_Conventional build:_\n\n    $ make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image test\n\n_Stand-alone build:_\n\n    $ make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image \\\n        openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test\n\n#### Windows (Cygwin):\n_Prerequisite:_ Build OpenJDK 7 according to [this site](http://weblogs.java.net/blog/simonis/archive/2011/10/28/yaojowbi-yet-another-openjdk-windows-build-instruction).  Alternatively, use https://github.com/alexkasko/openjdk-unofficial-builds.\n\n_Conventional build:_\n\n    $ make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image test\n\n_Stand-alone build:_\n\n    $ make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image \\\n        openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test\n\nCurrently, only OpenJDK 7 is supported.  Later versions might work,\nbut have not yet been tested.\n\n\nBuilding with the Android Class Library\n---------------------------------------\nAs an alternative to both the Avian and OpenJDK class libaries, you\ncan also build with the Android class library. Now it should work on Linux, OS X and Windows.\n\nThe simpliest way to build Avian with Android classpath is to use `avian-pack` project: https://github.com/bigfatbrowncat/avian-pack\n\nAvian-pack consists of Avian itself with some Android components (such as libcore and icu4c).\n\nNote that we use the upstream OpenSSL repository and apply the\nAndroid patches to it.  This is because it is not clear how to build\nthe Android fork of OpenSSL directly without checking out and building\nthe entire platform.  As of this writing, the patches apply cleanly\nagainst OpenSSL 1.0.1h, so that's the tag we check out, but this may\nchange in the future when the Android fork rebases against a new\nOpenSSL version.\n\nInstalling\n----------\n\nInstalling Avian is as simple as copying the executable to the desired\ndirectory:\n\n    $ cp build/${platform}-${arch}/avian ~/bin/\n\n\nEmbedding\n---------\n\nThe following series of commands illustrates how to produce a\nstand-alone executable out of a Java application using Avian.\n\nNote: if you are building on Cygwin, prepend \"x86_64-w64-mingw32-\" or\n\"i686-w64-mingw32-\" to the ar, g++, gcc, strip, and dlltool commands\nbelow (e.g. x86_64-w64-mingw32-gcc).\n\n__1.__ Build Avian, create a new directory, and populate it with the\nVM object files and bootstrap classpath jar.\n\n    $ make\n    $ mkdir hello\n    $ cd hello\n    $ ar x ../build/${platform}-${arch}/libavian.a\n    $ cp ../build/${platform}-${arch}/classpath.jar boot.jar\n\n__2.__ Build the Java code and add it to the jar.\n\n    $ cat \u003eHello.java \u003c\u003cEOF\n    public class Hello {\n      public static void main(String[] args) {\n        System.out.println(\"hello, world!\");\n      }\n    }\n    EOF\n     $ javac -bootclasspath boot.jar Hello.java\n     $ jar u0f boot.jar Hello.class\n\n__3.__ Make an object file out of the jar.\n\n    $ ../build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar \\\n         boot-jar.o _binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch}\n\nIf you've built Avian using the `lzma` option, you may optionally\ncompress the jar before generating the object:\n\n      ../build/$(platform}-${arch}-lzma/lzma/lzma encode boot.jar boot.jar.lzma\n         \u0026\u0026 ../build/${platform}-${arch}-lzma/binaryToObject/binaryToObject \\\n           boot.jar.lzma boot-jar.o _binary_boot_jar_start _binary_boot_jar_end \\\n           ${platform} ${arch}\n\nNote that you'll need to specify \"-Xbootclasspath:[lzma.bootJar]\"\ninstead of \"-Xbootclasspath:[bootJar]\" in the next step if you've used\nLZMA to compress the jar.\n\n__4.__ Write a driver which starts the VM and runs the desired main\nmethod.  Note the bootJar function, which will be called by the VM to\nget a handle to the embedded jar.  We tell the VM about this jar by\nsetting the boot classpath to \"[bootJar]\".\n\n    $ cat \u003eembedded-jar-main.cpp \u003c\u003cEOF\n    #include \"stdint.h\"\n    #include \"jni.h\"\n    #include \"stdlib.h\"\n\n    #if (defined __MINGW32__) || (defined _MSC_VER)\n    #  define EXPORT __declspec(dllexport)\n    #else\n    #  define EXPORT __attribute__ ((visibility(\"default\"))) \\\n      __attribute__ ((used))\n    #endif\n\n    #if (! defined __x86_64__) \u0026\u0026 ((defined __MINGW32__) || (defined _MSC_VER))\n    #  define SYMBOL(x) binary_boot_jar_##x\n    #else\n    #  define SYMBOL(x) _binary_boot_jar_##x\n    #endif\n\n    extern \"C\" {\n\n      extern const uint8_t SYMBOL(start)[];\n      extern const uint8_t SYMBOL(end)[];\n\n      EXPORT const uint8_t*\n      bootJar(size_t* size)\n      {\n        *size = SYMBOL(end) - SYMBOL(start);\n        return SYMBOL(start);\n      }\n\n    } // extern \"C\"\n\n    extern \"C\" void __cxa_pure_virtual(void) { abort(); }\n\n    int\n    main(int ac, const char** av)\n    {\n      JavaVMInitArgs vmArgs;\n      vmArgs.version = JNI_VERSION_1_2;\n      vmArgs.nOptions = 1;\n      vmArgs.ignoreUnrecognized = JNI_TRUE;\n\n      JavaVMOption options[vmArgs.nOptions];\n      vmArgs.options = options;\n\n      options[0].optionString = const_cast\u003cchar*\u003e(\"-Xbootclasspath:[bootJar]\");\n\n      JavaVM* vm;\n      void* env;\n      JNI_CreateJavaVM(\u0026vm, \u0026env, \u0026vmArgs);\n      JNIEnv* e = static_cast\u003cJNIEnv*\u003e(env);\n\n      jclass c = e-\u003eFindClass(\"Hello\");\n      if (not e-\u003eExceptionCheck()) {\n        jmethodID m = e-\u003eGetStaticMethodID(c, \"main\", \"([Ljava/lang/String;)V\");\n        if (not e-\u003eExceptionCheck()) {\n          jclass stringClass = e-\u003eFindClass(\"java/lang/String\");\n          if (not e-\u003eExceptionCheck()) {\n            jobjectArray a = e-\u003eNewObjectArray(ac-1, stringClass, 0);\n            if (not e-\u003eExceptionCheck()) {\n              for (int i = 1; i \u003c ac; ++i) {\n                e-\u003eSetObjectArrayElement(a, i-1, e-\u003eNewStringUTF(av[i]));\n              }\n\n              e-\u003eCallStaticVoidMethod(c, m, a);\n            }\n          }\n        }\n      }\n\n      int exitCode = 0;\n      if (e-\u003eExceptionCheck()) {\n        exitCode = -1;\n        e-\u003eExceptionDescribe();\n      }\n\n      vm-\u003eDestroyJavaVM();\n\n      return exitCode;\n    }\n    EOF\n\n__on Linux:__\n\n     $ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \\\n         -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o\n\n__on Mac OS X:__\n\n     $ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin \\\n         -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o\n\n__on Windows:__\n\n     $ g++ -fno-exceptions -fno-rtti -I\"$JAVA_HOME/include\" -I\"$JAVA_HOME/include/win32\" \\\n         -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o\n\n__5.__ Link the objects produced above to produce the final\nexecutable, and optionally strip its symbols.\n\n__on Linux:__\n\n    $ g++ -rdynamic *.o -ldl -lpthread -lz -o hello\n    $ strip --strip-all hello\n\n__on Mac OS X:__\n\n    $ g++ -rdynamic *.o -ldl -lpthread -lz -o hello -framework CoreFoundation\n    $ strip -S -x hello\n\n__on Windows:__\n\n    $ dlltool -z hello.def *.o\n    $ dlltool -d hello.def -e hello.exp\n    $ gcc hello.exp *.o -L../../win32/lib -lmingwthrd -lm -lz -lws2_32 \\\n        -lIphlpapi -mwindows -mconsole -o hello.exe\n    $ strip --strip-all hello.exe\n\nEmbedding with ProGuard and a Boot Image\n----------------------------------------\n\nThe following illustrates how to embed an application as above, except\nthis time we preprocess the code using ProGuard and build a boot image\nfrom it for quicker startup.  The pros and cons of using ProGuard are\nas follow:\n\n * Pros: ProGuard will eliminate unused code, optimize the rest, and\n   obfuscate it as well for maximum space savings\n\n * Cons: increased build time, especially for large applications, and\n   extra effort needed to configure it for applications which rely\n   heavily on reflection and/or calls to Java from native code\n\nFor boot image builds:\n\n * Pros: the boot image build pre-parses all the classes and compiles\n   all the methods, obviating the need for JIT compilation at runtime.\n   This also makes garbage collection faster, since the pre-parsed\n   classes are never visited.\n\n * Cons: the pre-parsed classes and AOT-compiled methods take up more\n   space in the executable than the equivalent class files.  In\n   practice, this can make the executable 30-50% larger.  Also, AOT\n   compilation does not yet yield significantly faster or smaller code\n   than JIT compilation.  Finally, floating point code may be slower\n   on 32-bit x86 since the compiler cannot assume SSE2 support will be\n   available at runtime, and the x87 FPU is not supported except via\n   out-of-line helper functions.\n\nNote you can use ProGuard without using a boot image and vice-versa,\nas desired.\n\nThe following instructions assume we are building for Linux/x86_64.\nPlease refer to the previous example for guidance on other platforms.\n\n__1.__ Build Avian, create a new directory, and populate it with the\nVM object files.\n\n    $ make bootimage=true\n    $ mkdir hello\n    $ cd hello\n    $ ar x ../build/linux-x86_64-bootimage/libavian.a\n\n__2.__ Create a stage1 directory and extract the contents of the\nclass library jar into it.\n\n    $ mkdir stage1\n    $ (cd stage1 \u0026\u0026 jar xf ../../build/linux-x86_64-bootimage/classpath.jar)\n\n__3.__ Build the Java code and add it to stage1.\n\n     $ cat \u003eHello.java \u003c\u003cEOF\n    public class Hello {\n      public static void main(String[] args) {\n        System.out.println(\"hello, world!\");\n      }\n    }\n    EOF\n     $ javac -bootclasspath stage1 -d stage1 Hello.java\n\n__4.__ Create a ProGuard configuration file specifying Hello.main as\nthe entry point.\n\n     $ cat \u003ehello.pro \u003c\u003cEOF\n    -keep class Hello {\n       public static void main(java.lang.String[]);\n     }\n    EOF\n\n__5.__ Run ProGuard with stage1 as input and stage2 as output.\n\n     $ java -jar ../../proguard4.6/lib/proguard.jar \\\n         -dontusemixedcaseclassnames -injars stage1 -outjars stage2 \\\n         @../vm.pro @hello.pro\n\n(note: The -dontusemixedcaseclassnames option is only needed when\nbuilding on systems with case-insensitive filesystems such as Windows\nand OS X.  Also, you'll need to add -ignorewarnings if you use the\nOpenJDK class library since the openjdk-src build does not include all\nthe JARs from OpenJDK, and thus ProGuard will not be able to resolve\nall referenced classes.  If you actually plan to use such classes at\nruntime, you'll need to add them to stage1 before running ProGuard.\nFinally, you'll need to add @../openjdk.pro to the above command when\nusing the OpenJDK library.)\n\n__6.__ Build the boot and code images.\n\n     $ ../build/linux-x86_64-bootimage/bootimage-generator \\\n        -cp stage2 \\\n        -bootimage bootimage-bin.o \\\n        -codeimage codeimage-bin.o \\\n        -hostvm ../build/linux-x86_64-interpret/libjvm.so\n\nNote that you can override the default names for the start and end\nsymbols in the boot/code image by also passing:\n\n    -bootimage-symbols my_bootimage_start:my_bootimage_end \\\n    -codeimage-symbols my_codeimage_start:my_codeimage_end\n\n__7.__ Write a driver which starts the VM and runs the desired main\nmethod.  Note the bootimageBin function, which will be called by the\nVM to get a handle to the embedded boot image.  We tell the VM about\nthis function via the \"avian.bootimage\" property.\n\nNote also that this example includes no resources besides class files.\nIf our application loaded resources such as images and properties\nfiles via the classloader, we would also need to embed the jar file\ncontaining them.  See the previous example for instructions.\n\n    $ cat \u003ebootimage-main.cpp \u003c\u003cEOF\n    #include \"stdint.h\"\n    #include \"jni.h\"\n\n    #if (defined __MINGW32__) || (defined _MSC_VER)\n    #  define EXPORT __declspec(dllexport)\n    #else\n    #  define EXPORT __attribute__ ((visibility(\"default\")))\n    #endif\n\n    #if (! defined __x86_64__) \u0026\u0026 ((defined __MINGW32__) || (defined _MSC_VER))\n    #  define BOOTIMAGE_BIN(x) binary_bootimage_bin_##x\n    #  define CODEIMAGE_BIN(x) binary_codeimage_bin_##x\n    #else\n    #  define BOOTIMAGE_BIN(x) _binary_bootimage_bin_##x\n    #  define CODEIMAGE_BIN(x) _binary_codeimage_bin_##x\n    #endif\n\n    extern \"C\" {\n\n      extern const uint8_t BOOTIMAGE_BIN(start)[];\n      extern const uint8_t BOOTIMAGE_BIN(end)[];\n\n      EXPORT const uint8_t*\n      bootimageBin(size_t* size)\n      {\n        *size = BOOTIMAGE_BIN(end) - BOOTIMAGE_BIN(start);\n        return BOOTIMAGE_BIN(start);\n      }\n\n      extern const uint8_t CODEIMAGE_BIN(start)[];\n      extern const uint8_t CODEIMAGE_BIN(end)[];\n\n      EXPORT const uint8_t*\n      codeimageBin(size_t* size)\n      {\n        *size = CODEIMAGE_BIN(end) - CODEIMAGE_BIN(start);\n        return CODEIMAGE_BIN(start);\n      }\n\n    } // extern \"C\"\n\n    int\n    main(int ac, const char** av)\n    {\n      JavaVMInitArgs vmArgs;\n      vmArgs.version = JNI_VERSION_1_2;\n      vmArgs.nOptions = 2;\n      vmArgs.ignoreUnrecognized = JNI_TRUE;\n\n      JavaVMOption options[vmArgs.nOptions];\n      vmArgs.options = options;\n\n      options[0].optionString\n        = const_cast\u003cchar*\u003e(\"-Davian.bootimage=bootimageBin\");\n\n      options[1].optionString\n        = const_cast\u003cchar*\u003e(\"-Davian.codeimage=codeimageBin\");\n\n      JavaVM* vm;\n      void* env;\n      JNI_CreateJavaVM(\u0026vm, \u0026env, \u0026vmArgs);\n      JNIEnv* e = static_cast\u003cJNIEnv*\u003e(env);\n\n      jclass c = e-\u003eFindClass(\"Hello\");\n      if (not e-\u003eExceptionCheck()) {\n        jmethodID m = e-\u003eGetStaticMethodID(c, \"main\", \"([Ljava/lang/String;)V\");\n        if (not e-\u003eExceptionCheck()) {\n          jclass stringClass = e-\u003eFindClass(\"java/lang/String\");\n          if (not e-\u003eExceptionCheck()) {\n            jobjectArray a = e-\u003eNewObjectArray(ac-1, stringClass, 0);\n            if (not e-\u003eExceptionCheck()) {\n              for (int i = 1; i \u003c ac; ++i) {\n                e-\u003eSetObjectArrayElement(a, i-1, e-\u003eNewStringUTF(av[i]));\n              }\n\n              e-\u003eCallStaticVoidMethod(c, m, a);\n            }\n          }\n        }\n      }\n\n      int exitCode = 0;\n      if (e-\u003eExceptionCheck()) {\n        exitCode = -1;\n        e-\u003eExceptionDescribe();\n      }\n\n      vm-\u003eDestroyJavaVM();\n\n      return exitCode;\n    }\n    EOF\n\n     $ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \\\n         -D_JNI_IMPLEMENTATION_ -c bootimage-main.cpp -o main.o\n\n__8.__ Link the objects produced above to produce the final\n executable, and optionally strip its symbols.\n\n    $ g++ -rdynamic *.o -ldl -lpthread -lz -o hello\n    $ strip --strip-all hello\n\n\nTrademarks\n----------\n\nOracle and Java are registered trademarks of Oracle and/or its\naffiliates.  Other names may be trademarks of their respective owners.\n\nThe Avian project is not affiliated with Oracle.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freadytalk%2Favian","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freadytalk%2Favian","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freadytalk%2Favian/lists"}