{"id":21944992,"url":"https://github.com/alexanderschuetz97/bettercoercion","last_synced_at":"2025-10-10T15:03:36.609Z","repository":{"id":60284510,"uuid":"514369045","full_name":"AlexanderSchuetz97/BetterCoercion","owner":"AlexanderSchuetz97","description":"BetterCoercion is a library for LuaJ that improves the coercion mechanics of LuaJ, making it easier to integrate LuaJ into a Java application.","archived":false,"fork":false,"pushed_at":"2023-12-19T19:30:57.000Z","size":262,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-22T16:15:44.453Z","etag":null,"topics":["java","library","luaj"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlexanderSchuetz97.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-07-15T18:32:02.000Z","updated_at":"2022-09-12T22:59:20.000Z","dependencies_parsed_at":"2023-12-20T11:19:48.019Z","dependency_job_id":"5e87a315-0d90-4e47-a12d-edd631a35058","html_url":"https://github.com/AlexanderSchuetz97/BetterCoercion","commit_stats":{"total_commits":8,"total_committers":2,"mean_commits":4.0,"dds":0.125,"last_synced_commit":"7d75023918ff785d37158cc612b58db3b39eaad4"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AlexanderSchuetz97/BetterCoercion","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderSchuetz97%2FBetterCoercion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderSchuetz97%2FBetterCoercion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderSchuetz97%2FBetterCoercion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderSchuetz97%2FBetterCoercion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlexanderSchuetz97","download_url":"https://codeload.github.com/AlexanderSchuetz97/BetterCoercion/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderSchuetz97%2FBetterCoercion/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279004565,"owners_count":26083734,"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","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","library","luaj"],"created_at":"2024-11-29T04:17:34.125Z","updated_at":"2025-10-10T15:03:36.574Z","avatar_url":"https://github.com/AlexanderSchuetz97.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BetterCoercion Readme\n\nBetterCoercion is a library for LuaJ that improves the coercion mechanics of LuaJ, making it easier to integrate LuaJ into a Java application.\n\n## License\n\nBetterCoercion is released under the GNU Lesser General Public License Version 3. \u003cbr\u003eA copy of the GNU Lesser General Public\nLicense Version 3 can be found in the COPYING \u0026 COPYING.LESSER files.\u003cbr\u003e\n\n## Dependency\nMaven:\n````\n\u003cdependency\u003e\n  \u003cgroupId\u003eeu.aschuetz\u003c/groupId\u003e\n  \u003cartifactId\u003eBetterCoercion\u003c/artifactId\u003e\n  \u003cversion\u003e0.2.2\u003c/version\u003e\n\u003c/dependency\u003e\n````\n\n## Features\n### From Lua:\n\n| routine                                                  | return value | description                                                                                                                                                                                                                                                                                                                                                                                                |\n|----------------------------------------------------------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `java.bindClass(string)`                                 | `userdata`   | Same behavior as LuaJavaLib equivalent                                                                                                                                                                                                                                                                                                                                                                     |\n| `java.new(string)`                                       | `userdata`   | Same behavior as LuaJavaLib equivalent                                                                                                                                                                                                                                                                                                                                                                     |\n| `java.loadLib(string, string)`                           | `varies`     | Same behavior as LuaJavaLib equivalent                                                                                                                                                                                                                                                                                                                                                                     |\n| `java.createProxy(string..., table)`                     | `userdata`   | Same behavior as LuaJavaLib equivalent                                                                                                                                                                                                                                                                                                                                                                     |\n| `java.toBigInteger(string/number/userdata)`              | `userdata `  | Turns parameter into a BigInteger for Strings the value must be acceptable by the BigInteger constructor. Userdata must be instance of java.lang.Number                                                                                                                                                                                                                                                    |\n| `java.toBigDecimal(string/number/userdata)`              | `userdata`   | Turns parameter into a BigDecimal for Strings the value must be acceptable by the BigDecimal constructor. Userdata must be instance of java.lang.Number                                                                                                                                                                                                                                                    |\n| `java.newArray(string/Class, number...)`                 | `userdata`   | Makes a java array userdata. string/class must be the arrays component type. number... is array size per array dimension.                                                                                                                                                                                                                                                                                  |\n| `java.toArray(string/Class, table)`                      | `userdata`   | Create a java array based on the table                                                                                                                                                                                                                                                                                                                                                                     |\n| `java.newCollection(Class/ParameterizedType, [class])`   | `userdata`   | Create a new Collection. By default component type is Object, a second class can be specified to enable type checking for the Collection.                                                                                                                                                                                                                                                                  |\n| `java.newMap(Class/ParameterizedType, [Class], [Class])` | `userdata`   | Create a new Map. By default key and value type is Object. More parameters can be specified to enable type checking for the Map.                                                                                                                                                                                                                                                                           |\n| `java.bindGenericType(Class, table/Class..., )`          | `userdata`   | Create a new ParameterizedType that can be used to create a Map or Collection with defined generic Type parameters.                                                                                                                                                                                                                                                                                        |\n| `java.bindTableInstance(userdata, [Class]..., )`         | `table`      | Create a table of functions that contains all non static methods of the userdata. Each function is bound to the supplied instance and can be called without the instance as the first parameter. This removes the need of useing the ':' operator. Any provided as 2nd parameter should be interfaces. If any interface  is provided the table will only contain methods found in any of the interfaces.   |\n| `java.bindUserdataInstance(userdata, [Class]..., )`      | `userdata`   | Create a userdata that reveals all non static methods of the userdata as functions. Each function is bound to the supplied instance and can be called without the instance as the first parameter. This removes the need of useing the ':' operator. Any provided as 2nd parameter should be interfaces. If any interface  is provided the table will only contain methods found in any of the interfaces. |\n\n#### Reflection\nEach userdata object created by BetterCoercion can be reflected to allow for fast and painless access to internal variables.\nTo  reflect a userdata simply index it by using the a '?' prefix. Example to get the private field \"blah\" from a userdata would be:\n````\nvalue = userdata[\"?fblah\"]\nuserdata[\"?fblah\"] = newValue\n````\nIn order to get a member from the parent class of the userdata simply append a ? for each time you wish to go up another level\nexample to access the field blah declared in the parent of the parent of the userdata class:\n````\nvalue = userdata[\"???fblah\"]\nuserdata[\"???fblah\"] = newValue\n````\nAvailable tokens for Reflection:\n\n| token              | description                             | example                                                                                 |\n|--------------------|-----------------------------------------|-----------------------------------------------------------------------------------------|\n| ?f(name)           | access field with hiding                | `u[\"?fblah\"] = 1`                                                                       |\n| ?m(name)           | access method                           | `u[\"?mblub\"](u, \"some parameter\")`                                                      |\n| ?m(name);SIGNATURE | access method by parameter signature    | `u[\"?mblub;Ljava/lang/String;JI\"]` for method `private Object blub(String, long, int);` |\n| ?c                 | get the class of the userdata           | `u[\"?c\"]`                                                                               |\n| ?ct                | get the type of class in userdata array | `u[\"?ct\"]`                                                                              |\n| _(name)            | access field without hiding             | `u._blah = 1`                                                                           |\n\nEach userdata object created by BetterCoercion can  be iterated over as if it were a normal lua table using the 'in pairs(userdata)'\npattern to get all fields and methods exposed by the userdata.\n\n\n##### Comparison of \"_(name)\" and \"?f(name)\"\nThey differ in regard to field hiding.\n_(name) can only ever access the first layer of fields. It will never access hidden fields.\n?f can access hidden fields.\n\nExample java classes that have hidden fields:\n```\nclass A {\n    private int a = 0;\n\n    public int getAa() {\n        return a;\n    }\n}\n\nclass B extends A {\n    private int a = 0; //this hides class A.a\n    \n    public int getBa() {\n        return a;\n    }\n}\n\n```\n\nGiven an instance of B: \u003cbr\u003e\n\n| lua                    | getBa() | getAa() |\n|------------------------|---------|---------|\n| `instance._a = 1`      | 1       | 0       |\n| `instance[\"?fa\"] = 1`  | 1       | 0       |\n| `instance[\"?f?a\"] = 1` | 0       | 1       |\n\nNote that the _ syntax can only be used if no actual java field or method with the same name exists!\n\n\n#### Collections and Maps\nJava  Collections, Java Iterators and Java Maps can be iterated over by using the standard lua 'in pairs(userdata)' pattern.\nIn addition to that Collections and Maps overload the lua '#' operator allowing for faster access to their size() methods.\n\n#### BigDecimal and BigInteger\nEach userdata from BigDecimal or BigInteger has all the mathematical and comparison operators overloaded.\nYou dont need to (but still can!) do: \n````\nbd = bd:add(bd2)\n````\nNow you have the option to do\n````\nbd = bd + bd2\n````\nThis should allow you to simplify code that deals with BigDecimals and BigIntegers\n\n#### Java enums\nFor the purpose of calling java methods and setting object fields strings are automatically coerced to the required java enum. This only works\nif the java parameter or field is an enum. Interfaces that are implemented by enums will not work. \nIf all constants in the enum are case-insensitive (There are no 2 constants with the same characters that only differ in upper and lower case)\nthen the lua strings can also have any case and will be matched to the appropriate case when determining the java enum the string will be coerced to.\n\nNote: You can still call the methods or set fields with userdata instances of the enum, the ability to do so with a string is just additional.\nThis has no effect on returned values from java methods. If a java method returns a enum then the returned value will always be a userdata instance of the enum.\n\n### From Java:\n- Register custom coercion/conversion handlers for your own types.\n- Implement Modules/Services/Beans in Java for use by Lua without the requirement to extend from LuaValue or wrap every call into a VarArgFunction\n- Coerce byte[] and char[] to actual mutable arrays instead coercing them to LuaString\n- Support for coercing LuaValue/Varargs internal types. You can now freely mix and match in between letting userdata take care of all, some and no coercion even within the same class.\n\n## Examples\n\n### Basic Example:\n\nIn Java:\n````\nGlobals globals = JsePlatform.standardGlobals();\n //Default lib name is 'java'\nglobals.load(new BetterCoercionLib());\n\n//We can however tell it to overwrite the default LuaJavaLib as we provide the same functions and more.\nglobals.load(new BetterCoercionLib(\"luajava\")); \n//.... (Standart LuaJ from this point)\nglobals.load(new InputStreamReader(new FileInputStream(\"test.lua\")), \"test.lua\").call();\n````\nIn test.lua:\n````\nlocal java = require('luajava')\nlocal JOptionPane = java.bindClass(\"javax.swing.JOptionPane\")\nJOptionPane:showConfirmDialog(nil, \"Hello World\")\n\njava = require('java')\nJOptionPane = java.bindClass(\"javax.swing.JOptionPane\")\nJOptionPane:showConfirmDialog(nil, \"Hello World 2\")\n````\n\n### Implementing a Module/Service/Bean for Lua in Java\nService Interface:\n````\npublic interface MyService {\n\n    String makeString(float input);\n    \n    int[] makeIntArray(int input)\n\n    void doSpecial(Varargs args);\n}\n````\n\nService Implementation:\n````\npublic interface MyServiceImpl implements MyService {\n\n    public String makeString(float input) {\n        return \"My float is: \" + String.valueOf(input);\n    }\n    \n    public int[] makeIntArray(int input) {\n        int[] result = new int[input];\n        for (int i = 0; i \u003c result.length;  i++) {\n            result[i] = i*2;\n        }\n        \n        return result;\n    }\n\n    public void doSpecial(Varargs args)  {\n        System.out.println(args.arg1());\n    }\n}\n````\n\nIn Java:\n````\nGlobals globals = JsePlatform.standardGlobals();\nglobals.load(LuaType.bindInstanceAsModule(\"MyService\", MyServiceImpl.class, MyService.class));\n//.... (Standart LuaJ from this point)\nglobals.load(new InputStreamReader(new FileInputStream(\"test.lua\")), \"test.lua\").call();\n````\n\nIn test.lua:\n````\nlocal MyService = require('MyService')\nprint(MyService.makeString(23.4))\nprint(MyService.makeIntArray(5)[3])\nprint(MyService.doSpecial({}, 4, \"Mep\"))\n````\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexanderschuetz97%2Fbettercoercion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexanderschuetz97%2Fbettercoercion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexanderschuetz97%2Fbettercoercion/lists"}