Use Ruby ActiveRecord models in Java - java

I have a Ruby on Rails application with much business logic contained in the models. I also have a backend process in Java that needs to use the same business logic. How can I package the Rails app into a jar that I can call from Java (using JRuby)?
I need to access the code directly in Java for performance reasons. Performing an HTTP request has too much overhead. Using a message queue won't work as the access needs to be synchronous.

Have you looked at Warbler?
https://github.com/nicksieger/warbler
This will help you package your rails app into a war. Would that help you?
Alternatively, you could just look at the files warbler generates: it creates a .class file for each .rb file, and then generates a file that includes the .class file. Perhaps you could take them and package them into a jar.
Also, for some info on how to access activerecord from jruby outside the rails app, look at section 2.14 from the book 'JRuby Cookbook'. Basically, it involves reading the config from database.yml, and opening up a DB connection using ActiveRecord.establish_connection, then you are ready to access your models by just requiring them.

Related

Develop a simple plugin modular rest reachable service in Java

I want to develop a service that exposes a rest API to upload plugins and the plugins are locally executable, i.e. other classes from the server use them.
The plugins also:
The plugin should be a jar file that is submitted through the REST API and once is validated, is then made available through another API method to see the metadata and to execute.
Are not too complex (they should all contain at least a a class that extends of an abstract class or an interface implementation of an interface, the service) but could have their own dependencies.
The API allows to validate that the plugin is compliant with the service and that it declares some additional information on an XML or JSON file contained on the JAR.
Have some metadata that has to be exposed through the API (Version, who made it, is it usable, what data can it be handled) in Json form.
All implement an algorithm to perform some data crunch so they all have something like an execute() method. The result of executing this method is handled to another class, so is not totally important to expose it on the API.
Must be able to be uploaded and executed by the other server classes in runtime, so no restart is possible
The thing is that I am not sure where to start, since I had already developed some of the basic API on Spring-boot since it had all the things I needed to easily develop a REST API but the more I read about how to dynamically load modules (plugins) the more I see that Spring does not support this ind of thing and I am not sure a class loader or Service loader would work in that context.
I found out about OSGi framework but I honestly do not know it changing the whole technology stack will help me so I want to make sure it is the right answer, and if yes, then find some resources that point me in the right direction, e.g. some tutorial that implements something similar.
Thank you for any advice.
Checkout OSGi enRoute. It includes a model to developing RESTful services: http://enroute.osgi.org/services/osgi.enroute.rest.api.html.
OSGi sounds like the best match to what you try to do.
You can install everything as a bundle including your main application. Nowadays this is much less work than some years before but still not to be underestimated.
The other option is to start an embedded OSGi framework where you just install your plugins. This is less work but you need to know exactly how it works.
So for both cases I suggest to get help from an external OSGi expert as it speeds up the transition a lot and avoids many wrong paths you will choose as a beginner.

Compile Jasper Report remoteley without Java-Bridge

Is there any way I can put jrxml files onto the Jasper server, link it to a datasource and let it compile without iReports, Java-Bridge, local Jaspersoft UI, ... I want to use as little Java as possible and I don't know about Apache ANT.
Can I do it through the (PHP) REST/SOAP API?
Or can I setup a little shell script on the Jasperserver that I can use like this way:
./compileMyReport.sh --report=/home/bla/test.jrxml --datasource=MongoDB_test_1
What do you mean by "Jasper server"? Do you mean the "JasperReports Server - Web Application" (http://community.jaspersoft.com/project/jasperreports-server)? If so, it does offer a REST interface. Have a look at the "JasperReports Server Web Service Guide" (http://community.jaspersoft.com/documentation?version=7114).
If you, however, only want to have reports somewhere and execute them programmatically that can also be arranged (and would be much easier than to go via the JasperServer Rest Interface). For this you would only need to set up a minimal java class. You could then simply call this "script" via a e.g. a system call and let it generate the report to disk. I've recently blogged about a security issue with jasperreports and there I'll also give the necessary code to execute jaspers: http://blog.datenwerke.net/2013/05/jasperreports-in-box-part-i.html
Hope that helps.

How can one deploy common JavaScript and images to two different EARs while not having to maintain two versions of each file

I have a Struts web app deployed to an EAR that has some pretty extensive JavaScript. I now need to create a new web app that will be deployed to a new EAR but will probably need to share most if not all of the JavaScript and some images from the first application. What's the best way to avoid code duplication so I don't have to put a copy of each JavaScript file in each EAR in my development environment?
You could maintain the Javascript in a separate .jar library and serve it as a resource, not as a static file. That way the JS content would be a regular dependency in your project setup. Unfortunately there isn't a straightforward universal way to do this because you need at the very least a servlet that will send the file from the .jar. (Depending on your web framework you might already have this available.)
This also has some performance implications, but for a line of business application you probably don't need to optimize the load time of your internal Javascripts all that heavily.
Another alternative would be doing this at the source control level, using something like Git submodules.

Custom classloader, JSP execution and resource retrieval inside webapp

Due project requirements, I need to create a webapp that, when executing, will allow some users to upload zip files which are like small apps and will contain .class files, resources (images, css, js, ...) and even lib files. That zip file is almost like a war file.
Any way to code it easily? AFAIK I think I know how to code the custom ClassLoader to load classes from inside the zip file ( Java - Custom ClassLoader - trying to load a class using class file full path ) and even code the resource retrieval when requested by the browser but no idea of how to execute JSP files which will be inside the zip file or load the jar lib files inside the zip file.
EDIT: the webapp must manage applications loaded, there is no way to implement this as answered below because the webapps need the "master" webapp to live. Also that "master" webapp allows versioning of applications. The user will be able to upload a new version and upgrade to it and even do a downgrade if the new version starts to fail.
There is no easy way to do this. It's a lot of work. Classloaders are very finicky beasts. Arguably the bulk of the work of creating something like Tomcat is wrangling the class loaders, the rest is just configuration. And even after all these years, we still have problems.
Tomcat, for example, is very aggressive on how it tries to unload existing webapps, using internal information of the Java class libraries to try and hunt down places for class loader leaks, etc. And despite their efforts, there's still problems.
The latest version of Glassfish has (or will have) the ability to version application deployments. You might have good luck simply hacking on Tomcats internal routing and mapping code to manage versioning.
If you're running an EJB container, you could put your core services in the EJBs and let the WARs talk to them (you could do this with web services in a generic servlet container, but many EJB containers can convert Remote semantics in to Local semantics for calls in to the same container).
You can also look at OSGI. That's another real pain to manage, but it might have enough granularity to even give you versioning, but none of your users will want to use it. Did I mention it's a real pain to manage? We do this for dynamic loading of web content and logic, but we don't version this.
If you must have everything under control of a single WAR, then your best bet is to punt on Java and instead use a scripting language. You tend to have a bit more control over the runtime of scripting environment, particularly if you DON'T let them access arbitrary Java classes.
With this you can upload whatever payload you want, handle all of the dispatch yourself to static resources and logic (which means you get to handle the versioning aspect). Use something like Velocity for your "JSP" pages, and then use Javascript or whatever for logic.
The versioned environment can be pain to pull off. If you don't care about doing it atomically, it's obviously easier. If you can afford "down time" (bring v1 offline then bring up v2), it's a lot easier. If you're uploading the full contents of each version, it's really easy. My system allowed incremental changes and had copy-on-write semantics, so it was a lot harder. But I didn't really want to upload several Gb of media for each version.
The basic takeaway is that when dealing with Classloaders, there be dragons -- nothing is easy with those and there are alternatives that actually get code in to production rather than creating scars and pissed off dragons. Using a scripting language simplifies that immensely. All the rest is dispatch, and that can be done with a filter or servlet.
You WILL get the great joy of reimplementing a solid chunk of the HTTP protocol doing this, that's always a treat as well since the servlet container doesn't really expose that functionality to you. That is, you'll want to do that if you want to be a good citizen on the web. You could always just continually shove content down the clients throat, caching and proxies be damned.
You could manually create a WAR-like structures inside your web container webapps directory and put classes, JARs and JSPs there.
Given that hot redeployment is enabled in your web container it would automatically designate a separate classloader to this new web application that it finds.
In most cases web containers consider any folder having a WEB-INF subfolder containing a valid web.xml file to be a web application. You can restrict access to this new webapp by modifying its context configuration, located in META-INF/context.xml in case of Tomcat.
Controlling hot redeployment, classloader policies etc is dependent on the type of your web container, but I hope your is not worse than Tomcat which could handle all of that.

Spring MVC Plugin Architecture

I am a novice with JavaEE but have some experience with ASP.NET MVC. With ASP.NET MVC, I know we can make a plugin architecture with ASP.NET MVC web app so you can make a dll with MVC structure and put it into the existing ASP.NET MVC web app to make it work without compiling the web app. http://www.wynia.org/wordpress/2008/12/05/aspnet-mvc-plugins/
I wonder if this kind of architecture is possible with Spring MVC. For example, when I make a jar (or war) file with MVC structure and put it into existing Spring MVC web app, it should work without recompiling the web app. If this is possible, how can I achieve that? Any reference would be appreciated.
It is possible without recompiling, but probably not without restarting. You could create a .jar which you drop into the WEB-INF/lib directory. By using classpath scanning you should be able to deploy your new controllers on start-up. You can skip the view entirely and directly output data to the ServletResponse. Rendering a view from a jar may or may not be possible, I don't know.
Sounds like you want to search for "hotdeploy".
What you are asking for is not a feature of Spring, but rather a feature of JVM and the application server. The application server is able to see that indeed your classes have changed and using some clever ClassLoader trickery it can load new versions to the runinng JVM as they become available. Java was not actually designed to work like this so there are some issues (ClassLoader, memory leak, hotdeploy are good keywords for finding more about the potential problems and possible solutions). I would not recommend this for production use but it can be handy during development.
Since this is a feature of the application servers, the actual details depend on the particular application server and are explained in it's documentation.
If you simply want some plugin-magic, not actual hotdeploy, there are other things you could do. A custom ClassLoader can load classes from whatever source (file, network, database..) you want and then you can instantiate and use these with reflection. (This is what happens when you deploy the war to Tomcat/JBoss or whatever). Accessing and dynamically reloading non-class resources inside jar/war files is way easier.

Categories

Resources