{"id":19923294,"url":"https://github.com/firebirdsql/fbjava","last_synced_at":"2025-08-22T22:09:24.247Z","repository":{"id":47677398,"uuid":"57854276","full_name":"FirebirdSQL/fbjava","owner":"FirebirdSQL","description":"FB/Java plugin for Firebird","archived":false,"fork":false,"pushed_at":"2023-11-30T01:05:12.000Z","size":579,"stargazers_count":12,"open_issues_count":6,"forks_count":6,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-07T13:11:09.662Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FirebirdSQL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-01T22:23:31.000Z","updated_at":"2023-11-30T01:05:11.000Z","dependencies_parsed_at":"2022-08-22T07:01:50.664Z","dependency_job_id":null,"html_url":"https://github.com/FirebirdSQL/fbjava","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FirebirdSQL%2Ffbjava","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FirebirdSQL%2Ffbjava/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FirebirdSQL%2Ffbjava/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FirebirdSQL%2Ffbjava/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FirebirdSQL","download_url":"https://codeload.github.com/FirebirdSQL/fbjava/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252156832,"owners_count":21703362,"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":[],"created_at":"2024-11-12T22:13:42.666Z","updated_at":"2025-05-03T07:31:03.470Z","avatar_url":"https://github.com/FirebirdSQL.png","language":"C++","readme":"[![GitHub Actions](https://github.com/FirebirdSQL/fbjava/workflows/build/badge.svg)](https://github.com/FirebirdSQL/fbjava/actions)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.firebirdsql.fbjava/fbjava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.firebirdsql.fbjava/fbjava/)\n\n# FB/Java External Engine Plugin for Firebird\n\nFB/Java is an External Engine plugin for Firebird that allows Firebird run\nfunctions, procedures and triggers made in the Java platform.\n\nFB/Java has also a client utility with functions to install and uninstall the plugin in a\ndatabase and that users may use to deploy and undeploy Java classes and resources stored in\nJAR files to a database.\n\nJaybird is bundled with FB/Java and allows to run queries using standard JDBC code.\n\n## Installing FB/Java in Firebird\n\nServer installation of FB/Java is a simple task involving three passes. The first\nnecessary pass is to extract the zip/tarball package in a place (subsequently named here as\n`\u003cfbjava-root\u003e` - this is the parent directory of the packaged bin and others directories).\n\nThe second pass is to include a line in the end of `\u003cfirebird-root\u003e/plugins.conf` file\npointing to the plugin:\n\n```\ninclude \u003cfbjava-root\u003e/conf/fbjava.conf\n```\n\nThe third pass is to define the environment variable JAVA_HOME pointing to the home directory\nof a JDK or JRE installation. Optionally this can be configured in `\u003cfbjava-root\u003e/conf/fbjava.conf`.\nFB/Java requires a Java 8 platform of the same architecture (32 or 64 bit) of Firebird.\n\nFB/Java can also be installed in the client making possible to use `fbjava-deployer`\nutility remotely. In this case it's just necessary to extract the zip/tarball in some directory\nand optionally add its bin directory to the `PATH` environment variable. Java `bin` directory must\nalso be in `PATH`.\n\nTo develop external routines using Java, Maven/Gradle users need to add this dependency:\n\n```\n\u003cdependency\u003e\n\t\u003cgroupId\u003eorg.firebirdsql.fbjava\u003c/groupId\u003e\n\t\u003cartifactId\u003efbjava\u003c/artifactId\u003e\n\t\u003cversion\u003e1.0.0-beta-1\u003c/version\u003e\n\t\u003cscope\u003eprovided\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n## Features\n\n### Database and Java routines mappings\n\nThere are basically two ways to map database functions and procedures to Java\nmethods. By fixed or generic signatures. Triggers can be mapped only with generic signatures.\n\n:information_source: Generics here does not refer to Java generics in any way.\n\n#### Fixed signatures\n\nFixed signatures means that for each database routine parameter there should be a\nJava parameter in the method.\n\n#### Generic signatures\n\nGeneric signatures doesn't have parameters. The Java code can obtain from the\ncall Context all parameters or fields values passed by the database routine.\n\n### Security\n\nOne of the more important features of the Java platform is it security system, the so\ncalled sandbox. FB/Java integrates the J2SE/JAAS security mechanism with Firebird so that\npermissions may be assigned to database users running the Java code.\n\nUsers permissions work at server level. They are stored in the\n`\u003cfbjava-root\u003e/conf/java-security.fdb` database.\n\nThat database contains the tables `PERMISSION_GROUP` (with columns `ID`, `NAME`),\n`PERMISSION` (with columns `PERMISSION_GROUP`, `CLASS_NAME`, `ARG1`, `ARG2`) and\n`PERMISSION_GROUP_GRANT` (with columns `PERMISSION_GROUP`, `DATABASE_PATTERN`,\n`GRANTEE_TYPE`, `GRANTEE_PATTERN`).\n\n`PERMISSION_GROUP` names a set of `PERMISSION` associated by `PERMISSION.PERMISSION_GROUP`\ncolumn.\n\nIn `PERMISSION` table, there is `CLASS_NAME` column which stores the Java permission class\nname and `ARG1` / `ARG2` which stores the arguments passed to the permission class constructor.\n\nThe `PERMISSION_GROUP_GRANT` table associates `PERMISSION_GROUP` with Firebird users and\nroles. This association is done by a `DATABASE_PATTERN` and a `GRANTEE_TYPE` / `GRANTEE_PATTERN`.\nPatterns are `SIMILAR TO` patterns escaped by the `'\u0026'` symbol. Pay attention when using special\n`SIMILAR TO` characters like underline, if they refer to actual database, user or role name\nparts, they need to be escaped. `GRANTEE_TYPE` defines if `GRANTEE_PATTERN` refers to a `ROLE` or\n`USER`.\n\nThe plugin ships with a number of permissions grouped as `COMMON` and granted to all\n(`%` pattern) users of all databases. They are:\n\n#### Default permissions granted\n\n| CLASS_NAME                   | ARG1            | ARG2 |\n| ---------------------------- | --------------- | ---- |\n| java.util.PropertyPermission | file.separator  | read |\n| java.util.PropertyPermission | java.version    | read |\n| java.util.PropertyPermission | java.vendor     | read |\n| java.util.PropertyPermission | java.vendor.url | read |\n| java.util.PropertyPermission | line.separator  | read |\n| java.util.PropertyPermission | os.*            | read |\n| java.util.PropertyPermission | path.separator  | read |\n\n:warning: Permissions configured in java-security.fdb are valid only for classes stored inside\ndatabases. Classes at file system are granted `java.security.AllPermission`.\n\n:information_source: The `java.security.AllPermission` is effectively valid in this context if\nthe code marks itself as privileged, like with `java.security.AccessController.doPrivileged` method.\n\n### ClassLoaders\n\nFB/Java looks for classes in two different places: the file system and the current\ndatabase, in this order. It is general recommendation that users store they classes in the\ndatabase.\n\nClasses in the file system are shared between all databases handled by a Firebird process.\nFor example, static variables have per-process values. In an analogy with an application server,\nthey are the system classes. The internal classes necessary for FB/Java are in\n`\u003cfbjava-root\u003e/jar/*.jar` and is not recommended to put more jar files there.\n\nClasses in the database are isolated per-database (and process) and unloaded when the last\nuser disconnects from the database/process. So static variables are shared between attachments\nto the same database, but are reinitialized when a closed database is opened. In an analogy with\nan application server, they are the application classes, although an application server does\nnot reload application classes when the application is idle.\n\n:information_source: Classes does not share static variables when used by different Classic or\nembedded processes.\n\n:information_source: Classes are unloaded by closing the database classloader.\nIt is subject to garbage collection to really unload them.\n\nClasses can be stored in the database by two different methods: the `fbjava-deployer`\n(`.bat` in Windows / `.sh` in Linux) utility or the `SQLJ` package.\n\n### `fbjava-deployer` utility\n\nFB/Java allows execution of Java routines stored in the file system without any\nper-database installation. But to have per-database classes, the plugin need to be installed\non the database.\n\n`fbjava-deployer` is the utility to install and uninstall the plugin in databases and to\ninstall, remove and replace JAR files in databases. Its command line options are:\n\n- `--database \u003cconnection string\u003e` - Jaybird connection string, without `jdbc:` prefix.\n\n- `--user \u003cuser name\u003e` - Database user name.\n\n- `--password \u003cpassword\u003e` - User password.\n\n- `--install-plugin` - Installs the plugin in the database. The installation process consists of the\ncreation of some database objects, prefixed with `FB$JAVA$` and the `SQLJ` package.\n\n:information_source: Details of the install process can be seen in the install.sql file in the\nscripts directory of the plugin.\n\n- `--uninstall-plugin` - Uninstalls the plugin from the database. The uninstall process consists of dropping\nall the objects created by the installation process.\n\n:information_source: Details of the uninstall process can be seen in the uninstall.sql file in the\nscripts directory of the plugin.\n\n:warning: All stored JARs are deleted when the plugin is uninstalled.\n\n- `--install-jar \u003cURL or filename\u003e \u003cname\u003e` - Installs a JAR in the database. `\u003cname\u003e` is an unique\nidentifier to refer to the JAR in subsequent calls, like `--replace-jar`,\n`--update-jar` or `--remove-jar`.\n\n- `--update-jar \u003cURL or filename\u003e \u003cname\u003e` - Updates an existing JAR in the database. It is an error to try to update a JAR with a `\u003cname\u003e` that is not installed.\n\n- `--replace-jar \u003cURL or filename\u003e \u003cname\u003e` - Replaces a JAR in the database. The replacement is done deleting the current JAR if it exists and installing the new one.\n\n- `--remove-jar \u003cname\u003e` - Removes a JAR from the database.\n\n### `SQLJ` package\n\nJAR installation, replacement, updation and remotion can also be done with the help\nof the `SQLJ` package. The `SQLJ` package just runs the same class used in `fbjava-deployer`, but in\nthe server, as Java stored procedures. With that package, paths and URLs are server-based. Its\nprocedures are:\n\n- `SQLJ.INSTALL_JAR(\u003cURL or filename\u003e, \u003cname\u003e)`\n\n- `SQLJ.UPDATE_JAR(\u003cURL or filename\u003e, \u003cname\u003e)`\n\n- `SQLJ.REPLACE_JAR(\u003cURL or filename\u003e, \u003cname\u003e)`\n\n- `SQLJ.REMOVE_JAR(\u003cname\u003e)`\n\n### Mapping database routines to Java methods\n\nDatabase routines are mapped to Java methods by a database declaration with an external call\nspecification and usage of `ENGINE JAVA` clause. The call specification consists of the method\nsignature, in this format:\n\n```\n\u003ccall specification\u003e ::=\n  \u003cfully qualified class name\u003e.\u003cstatic method name\u003e(\n      [\u003ctype\u003e [{, \u003ctype\u003e}...]])\n      [!\u003cname info\u003e]\n\n\u003ctype\u003e ::=\n  \u003cprimitive type\u003e |\n  \u003cfully qualified class name or unqualified class name from java.lang package\u003e\n```\n\n:information_source: The java.lang package prefix may be avoided in parameters types but not\nin the class name containing the static method.\n\n:information_source: `\u003cname info\u003e` prefixed by an exclamation point is an optional info you\ncan pass to the Java method that it can obtain with the method `getNameInfo` from the\n`Context` interface.\n\n#### Supported Java and Jaybird types\n\n| Java or Jaybird Type             | Compatible Firebird type | Notes |\n| --------------------------------- | ------------------------ | ----- |\n| byte[]                            | BLOB, CHAR, VARCHAR      |       |\n| boolean                           | any                      | [1]   |\n| short                             | any                      | [1]   |\n| int                               | any                      | [1]   |\n| long                              | any                      | [1]   |\n| float                             | any                      | [1]   |\n| double                            | any                      | [1]   |\n| java.lang.Boolean                 | any                      |       |\n| java.lang.Short                   | any                      |       |\n| java.lang.Integer                 | any                      |       |\n| java.lang.Long                    | any                      |       |\n| java.lang.Float                   | any                      |       |\n| java.lang.Double                  | any                      |       |\n| java.lang.Object                  | any                      | [2]   |\n| java.lang.String                  | any                      |       |\n| java.math.BigDecimal              | any                      |       |\n| java.sql.Blob                     | BLOB                     |       |\n| java.sql.Date                     | any                      |       |\n| java.sql.Time                     | any                      |       |\n| java.sql.Timestamp                | any                      |       |\n| java.util.Date                    | any                      |       |\n| org.firebirdsql.jdbc.FirebirdBlob | BLOB                     |       |\n\n\n:information_source: [1] A database NULL is converted to `0` (zero) when passed to\na primitive numeric type and `false` to `boolean`.\n\n:information_source: [2] Parameters and trigger values are converted accordingly to\ndefault mapping rules.\n\n:information_source: Any compatible type means the plugin doesn't care about the\ntype, it just tries to get the value as a Firebird type compatible with the Java type.\nBasically, this means that a CAST will be done from the Firebird value to the default\nmapping type of the Java type, or vice-versa.\n\n#### Default mappings\n\n| Firebird Type    | Java type            |\n| ---------------- | -------------------- |\n| NUMERIC          | java.math.BigDecimal |\n| DECIMAL          | java.math.BigDecimal |\n| SMALLINT         | java.math.BigDecimal |\n| INTEGER          | java.math.BigDecimal |\n| BIGINT           | java.math.BigDecimal |\n| FLOAT            | java.lang.Float      |\n| DOUBLE PRECISION | java.lang.Double     |\n| BOOLEAN          | java.lang.Boolean    |\n| CHAR             | java.lang.String     |\n| VARCHAR          | java.lang.String     |\n| BLOB             | java.sql.Blob        |\n| DATE             | java.sql.Date        |\n| TIME             | java.sql.Time        |\n| TIMESTAMP        | java.sql.Timestamp   |\n\n#### Functions mapping\n\nFunctions are the only routine type that always requires a non-void return type in the Java method.\n\nExamples:\n\n```\ncreate or alter function get_system_property (\n  name varchar(80)\n) returns varchar(80)\n  external name 'java.lang.System.getProperty(String)'\n  engine java;\n\n-- A single method being mapped to two different Firebird functions.\n\ncreate function funcSum2 (n1 integer, n2 integer) returns integer\n  external name 'org.firebirdsql.fbjava.FuncTest.sum()'\n  engine java;\n\ncreate function funcSum4 (n1 integer, n2 integer, n3 integer, n4 integer) returns integer\n  external name 'org.firebirdsql.fbjava.FuncTest.sum()'\n  engine java;\n```\n\n#### Procedures mapping\n\nProcedures can have a return type (of `org.firebirdsql.fbjava.ExternalResultSet` type or a\nclass implementing that interface) or `void`, depending of it being a selectable procedure or not.\nOutput parameters should appear on the call specification as arrays. FB/Java pass each output\nparameter as an array of length 1, and routines can change their `[0]` element.\n\nExamples:\n\n```\n-- Executable procedure.\ncreate procedure procInsert (n integer, s varchar(10))\n  external name 'org.firebirdsql.fbjava.ProcTest.insert(int, String)'\n  engine java;\n\n-- Selectable procedure.\ncreate procedure procGenRows (numRows integer) returns (n integer)\n  external name 'org.firebirdsql.fbjava.ProcTest.genRows(int, int[])'\n  engine java;\n```\n\n#### Triggers mapping\n\nCall specification of triggers has always zero parameter and the Java method should\nreturn `void`. Details of the call and the `OLD` and `NEW` values can be read and write from the\ncall context.\n\nExamples:\n\n```\ncreate or alter trigger employee_log_bdiu\n  before delete or insert or update on employee\n  external name 'org.firebirdsql.example.fbjava.FbLogger.info()'\n  engine java;\n```\n\n### Context\n\nJava code can obtain a `Context` object which has information about the Firebird routine\nthat mapped to the Java code as well inspect and manipulate metadata and data about the call.\nThe `Context` interface has the following hierarchy:\n\n- `CallableRoutineContext extends Context`\n- `FunctionContext extends CallableRoutineContext`\n- `ProcedureContext extends CallableRoutineContext`\n- `TriggerContext extends Context`\n\nAll these interfaces have a static get() method to obtain the object instance.\nMore details of what can be done from them can be consulted in the Java Docs present in\n`\u003cfbjava-root\u003e/docs/apidocs` or [online](https://htmlpreview.github.io/?https://raw.githubusercontent.com/FirebirdSQL/fbjava/1.0.0-beta-1/apidocs/org/firebirdsql/fbjava/package-summary.html).\n\n## Example\n\nThere is an example project in `examples/fbjava-example` directory with instructions in the README file.\n\n## Known issues\n\nIt's not possible to use Jaybird's non-pure-Java connection string protocols like embedded, native and local.\n\n## Sponsors\n\nThe FB/Java team would like to thank YourKit for providing licenses to their [YourKit Java Profiler](https://www.yourkit.com/java/profiler/).\n![YourKit](https://www.yourkit.com/images/yklogo.png)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirebirdsql%2Ffbjava","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffirebirdsql%2Ffbjava","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirebirdsql%2Ffbjava/lists"}