Download/Install
Download
The current version is 1.0.29 (requires JDK 8 and above).
Amazon corretto is
recommended for the JDK (this, IMO, is the true successor to the Sun and the OpenJDK).
(Changelog)
There is also a JDK 6 version available, which is exactly the same as JDK 8, except
is missing some misc/minor JDBC methods (missing in JDK6 since added in JDK 7+) (Changelog)
Due to increasing divergence between JDK 6/8, this will be the last version that will be available for JDK 6.
The download comes with full source, javadoc and compiled classes.
You can also recompile all classes from scratch (there are no
external dependencies).
Installing/Running
Molly can be used for standalone java programs or in a web-server/servlet environment. After downloading the molly package, you just have to make sure that either molly.jar or the compiled classes (unjar'ed) are in your classpath. There are several possibilites (unix examples shown):
For Standalone programs:
You can install molly in a location outside of your webserver.
unix> export CLASSSPATH=$CLASSPATH:/path/to/molly.jar
Then run this as your first program
unix> java fc.util.Version
If you see a welcome message, you are up and running successfully!
Alternately, you can specify the classpath to the java interpreter:
unix> java -cp $CLASSPATH:/path/to/molly.jar java fc.util.Version
Next, try generating some O/R classes and connecting to the database. The
following will print out usage information to the console.
unix> java fc.jdbc.dbo.Generate
You can get some sample configuration files (edit those to your environment) from the
O/R examples. The cookbook is also worth checking out.
For Web Applications:
You can also install molly.jar directly in your web server's
WEB-INF/lib directory. (See this for more details).
The webserver will automatically add this to it's java classpath. To run programs from the command
line, you would say:
unix> export CLASSSPATH=$CLASSPATH:/my/website/WEB-INF/lib/molly.jar
unix> java fc.io.HexOutputStream
Alternately, you can specify the classpath to the java interpreter:
unix> java -cp CLASSSPATH=$CLASSPATH:/my/website/WEB-INF/lib/molly.jar java fc.io.HexOutputStream
Changelog
1.0.29
- Changed the PageParser to generate code that keeps String literals less than 64K bytes. Pages
lines are output using something similar to
out("...")
in the PageServlet. Each line
in the source document is converted into these out statements. However, if the entire source document is
one large line (with no newlines) and that line size is massive (> 64K), the the generated code will fail
because Java string literals are limited by the classfile constant pool limitations (this limitation may
go away in future java variants but is true as of now).
This sort of thing can happen with machine generated XML files for example (uncommon but can happen).
We break such long lines into smaller chunks internally (without adding any spurious linebreaks) so what
you put in is exactly what you get out (and no compilation errors!)
1.0.28
- Added a BitUtil class for misc. Bit operations.
- Slight cleanup to BasicArgcheckFailHandler class
to have less noisy output
1.0.27
- The include-file pages tag is improved and
previous limitations (of not being able to contain directives, declarations, etc) are
removed.
- Internal refactoring and improvements to the molly pages parser and reader.
- JSON/JSONB data types are supported and returned as Objects by the DBO frameworks. These
are can be converted into Java JSON objects locally on the Java side (by passing these as Strings
to your JSON framework - whichever framework you are using).
- DBO framework prevents a edge case - an internal variable count would clash with a
column name "count" if used. Internal names start with __ now and that should be a
hopefully separate namespace. If your table column name happens to be (2 underscores) "__count", you are
still in trouble though!
- Although mysql testing has fallen by the wayside, a round of mysql testing for this release, just to
ensure the framewok is database independent. Both postgres and mysql work great.
1.0.26
- DBO Framework: added a deleteUsing variation that takes an optional WHERE clause
- Various misc. cleanups and tweaks
1.0.25
- Created a JDK 8 compatible version that compiles under JDK 8. JDK 6 is still supported but will be dropped afer this version.
1.0.24
-
In addition to the WebApp
that is created per servlet context/webapp, multiple WebApps can be manually
instantiated and added (under different names) in the same servlet
context/webapp. This is useful when there are multiple servlets running in
the same context, each of which need seperate connection pools, loggers,
etc; these servlets can use the existing WebApp functionality that reads a
config file and creates all this specific for each servlet (independent of
the shared context wide WebApp).
In particular, this is useful for servlets that support REST API versions,
/rest/v1/*, rest/v2/*, etc, and one can configure
different connection pool sizes and resources for each particular version of
the API, as opposed to using context wide shared resources for all the
different servlets in common.
1.0.23
-
The DBO Generate warns & exits early if a table or
column name is a Java Reserved Keyword because the generated
code wouldn't compile in that case anyway.
-
Added a MiscUtil
class.
-
Added a few more utility methods to CalendarUtil
1.0.22
-
Small tweaks and fixes throughout the framework.
1.0.21
-
DBO Framework: added the ability to save primitive fields as null if
they are nullable in the database. Primitive fields such as integer cannot be
null in Java yet the corresponding SQL fields can be null in the database. So,
for a field "x", there is now a method called "setNull_x()" (or similar),
which if called sends null for x to the database.
- Misc cleanups
1.0.20
- Changed WebApp
to be more sane (you now create a different WebApp instance per tomcat
webapp. Prior WebApp
usage (when molly classes were loaded via the system classpath) was 1
instance shared across all tomcat webapps, which meant each webapp would
overwrite the prior webapps configuration. The recommended way to install
the molly classes in each tomcat webapps separate jar directory (such that
it wasn't in the system classpath at all) was proving to be too much of a
hassle in practice.
- Misc cleanups
1.0.19
- Bug fix: IOUtil.sha1hash was missing a leading "0" in the hex value for bytes less than 16 (so "A" rather than "0A").
Thanks to Menelaos Perdikeas of Semantix Information Technologies, for the patch.
1.0.18
- Misc. tweaks and improvements to the DBO framework.
- Bug fix: When creating a new DBO object and saving it as a forced update (via the update method), the primary key parameters specified to the update method are used, rather than using the original primary key(s) (which are now only used internally for updates of objects retrieved from the database).
1.0.17
- Added a NamedParamStatement class. This makes it easier to work with JDBC PreparedStatements, instead of using ? and integer indexes, one can use named parameters instead. For example:
String query = "select * from foo where bar = @bar and baz = @baz";
NamedParamStatement ps = NamedParamStatement.get(con, query);
ps.setString("bar", "hello");
ps.setInt("baz", 42);
This is quite useful for larger, complicated queries with lots
of parameters.
-
Misc. improvements in in the DBO generate code that make it easier to use when using table aliases (using the SQL "AS" keyword).
For example, see columns(String) and getFromRS(ResultSet, prefix)
1.0.16
-
Fixed a bug in the DBO generate code that would cause an
error when updating a row after modifying it's primary key(s).
For example, consider the following table:
create table users (username varchar(255) primary key, age integer);
Now, we use DBO, generate our java objects and say:
users u = usersMgr.getByKey("molly");
u.set_username("case");
u.set_age(22);
usersMgr.save(con, u);
This would internally create & use a SQL update statement that
would look something like:
UPDATE users set username = 'case', age = '22' where username = 'case';
We update a row using the primary key but we are changing the primary key itself, which
means we can no longer find the original row to update.
This problem is fixed now, by having the generated DBO object internally save the original values of
all primary keys. These original values are then used when updating the row. In this example,
that would now look like:
UPDATE users set username = 'case', age = '22' where username = 'molly';
Dunno how this elementary bug managed to slip through,
undetected for so many years. Primary keys are not changed that
often, I guess. Just goes to show that no complex piece of
software is ever completely bug free.
- Fixed another bug in DBO. If setters were generated for SERIAL/auto-increment types,
and values were manually entered for those types, then those fields were not saved to the database.
1.0.15
- Added a CommentedFileReader class that
helps read files, ignoring any comments and whitespace.
With the existence of CommentedFileReader, FilePropertyMgr, IOUtil, StringUtil and Template, using property
& configuration files is easy.
1.0.14
- Added a QueryReader class that helps organize your
queries in a text file, external to your program. This
makes maintainence a lot easier.
- Note: We skipped version 1.0.13 for good luck
1.0.12
- Previously, when saving a new DBO object, if a particular field was
not-nullable in the database, it had to be set in the DBO object before
the object could be successfully saved/updated. Now, it does not have to
be set in the object, if the database also defines a default column value
for that non-nullable column.
- Many misc. tweaks & changes
1.0.11
- Fixed a bug in the DBO-generated manager class, where if an
autoincrement/serial column was not the first column in a table, then
saving a corresponding object would fail (when retrieving the new
auto increment value).
1.0.10
- Various little documentation fixes.
- The problem with the command java fc.jdbc.dbo.Generate not
printing its usage/help file has been solved. It wasn't a bug with the
Java classloader as previously thought. It was the fact that the help
file was missing from the published jar file (yeah, I know !)
- JDBCSession has been improved to not use static methods. I like using
static utility classes (as opposed to singletons) because they are simple. But if the utility class needs to be initialized (once) before being used, then, we have to remember to call the static initializer, which is easy to forget. So instead of saying:
JDBCSession.init(..);
JDBCSession.someMethod(..);
we now say:
JDBCSession session = JDBCSession.getInstance(); //does init if needed
session.someMethod();
- Added a cookbook link on the website, concurrently with this release.
-
A special thanks to Menelaos Perdikeas of Semantix Information Technologies, for
helping report and diagnose various issues.
1.0.9
- This version compiles and runs under JDK 1.6. The only change from the
previous version was some additional JDBC4 specific method signatures,
required for JDK 1.6 were added. Consequently, this version will not run
under JDK 1.5 and requires JDK 1.6 or greater.
1.0.8
- The configuration file for the DBO Generator
accepts both prefix and suffix * wildcards for table names to
exclude. (previously, a wildcard could only be applied to the include
tables). Added Clarifications to the include/exclude functionality in the
configuration file.
There is a problem with the command java fc.jdbc.dbo.Generate not
printing its usage/help file (due to a java bug with the classloader not
being able to load a resource from within a .jar). These usage/help
instructions have now been added to the javadoc as well to get around this problem.
I recently pointed the DBO Generator towards a real 400+ table enterprise
production database with all sorts of columns, tables and relationships. The
generator ran flawlessly and took about 30 seconds to generate and write
800+ classes (2 per table). So the Generator itself is super fast (perhaps
the fastest O/R in Java) and does work very nicely.
- The fc.util.Watch class can now
return elapsed time in seconds (in addition to milliseconds) which makes for
more user friendly output.
1.0.7
- Added the ability to use a thread local
java.util.Random
to WebApp
1.0.6
- Modified GzipFileServlet so the paths of included files
are relative to the document root (as opposed to web app
context as earlier). It is more intuitive for absolute paths
to be relative to the document root.
-
Added more methods to the Page interface
and improved the javadocs for both Page and
PageImpl.
-
Added a new Table class.
1.0.5
- Fixed a major bug in the PageMgr page reloading algorithm.
This bug caused the page class to be discarded and reloaded
as if the page had been modified, even when it hadn't. This
caused the static fields in the page to be reinitialized
at every page access, instead of when the page source was
modified.
All molly page users should immediately upgrade to this
release.
1.0.4
- Fixed a minor bug which caused the
PageMgr to throw an
exception when the webapp was restarted.
1.0.3
- The configuration file for the DBO Generator
accepts both prefix and suffix * wildcards for table names to
include. (previously, a wildcard could only be either a suffix or
a prefix but not both).
1.0.2
- Page forwards can now contain expressions. (Earlier, only
Page includes could contain expressions)
- Misc. javadoc clarifications.
1.0.1
- Added GzipFileServlet. This allows
serving of compressed html/js; this speeds things up considerably
when downloading javascript libraries
1.0
- Initial public release.