How to allow people to configure database information without editing code - java

What I am using:
Java EE
So, essentially I am making a web application that is free to use and open source, however I worry there will be users who are not familiar with java, I want these users to be able to configure DATABASE information without editing the code, would this be possible?
Things I want to try but don't know enough about:
- A installation page, kind of like the one WHMCS and Xenforo have, however I am not sure how to make this stick, for instance, if the user restarts there web server would the information be reset.

One way is,
You can make a way to read database details(hostname, port etc) from system environment variables. Users can set environment variables to add their DB details.
OR
You can create a docker image of your db and application and make a docker-compose file with details. then you can ask users to edit username/password in that file and then user will run 1 or 2 docker commands and application is up and ready.
Ex: fider is similar application and they provided through docker. for your reference https://getfider.com/docs/hosting-instance/
Note: this approach requires docker environment.

Since your deliverable is a war you expect the consumer to know their app container. The typical way for a JEE app to configure persistence layer is using persistence.xml file located in META-INF/ folder. You can tell the user to prepend class path with their own persistence configuration. I understand it may sound difficult but a typical system admin should know what you're asking. This is what war deliverable really means.
If you want to make it easy for lay people, build a docker image with a database of your choice and package with your app connected to this database. People who will want more will need handholding anyway. Hopefully in the form of their own developers.

Related

How to force my EAR files to just be deployed on an specific server?

I am developing an enterprise java application for a customer using J2EE technologies (JSF, EJB, Hibernate, etc). To avoid the customer to copy my .ear files and deploy them on another server (the AppServer is Weblogic), I am searching for a standard and secure method to bind my project output files into an specific physical server. This mean that I need my project output to be bound to a physical server at build time and the customer is just allowed to deploy then on an specific server.
Is there any standard method/library to do this or I should do it manually in my code using server identifiers?
I don't think that you will be able to 100% assure that a customer will be unable to copy, adapt and run your application to another server. First, an ear file is just a ZIP file, and classes inside are also easy to decompile and compile again, even if the EAR would be signed. So a lot of space to do some funny business :)
If you just wish to protect the customer from "accidentally" deploy your EAR on a second server, a first, easy and cheap step could be to link/insert the predicted host name (perhaps even the ip address) during the stage phase to a manifest or even java file (to make things more static). Then add an once initialized, later cached interceptor around all methods you would like to protect and check the local system (ie with InetAddress.getLocalHost()) against your preconfigured & linked host information. Still, very weak :/
If it's a MAVEN project you could add something to de settings.xml of the compilation server that allows things to run different on the configuration of the production system. Something like a different name for a datasource or something like that.

How to incremental update Java EE web application?

I have a typical web application deployed in Tomcat. The requirement is to provide incremental update way instead of full-package delivery (a war file) when update the application.
For example, once I finish a bug fix which changed a jar file, an XML file and jpg file. I call these 3 files as a patch. I am supposed to deliver the patch file. Even when customers want to rollback to original version, I have to provider a way to rollback the patch.
All the process is supposed to automatically.
From my perspective, the requirement doesn’t make sense. full-package delivery is easy and reliable way to update a web application, I don’t want to introduce complex and error-prone way to update.
Do you have idea to implement incremental update requirement? Thanks!
When you deploy the .war or .ear, the application server usually unpack it into an internal directory. You can change files in this directory directly, with a finer granularity. However, for changes to take effect consistently, you will need to restart the server.
Your perspective is indeed fully correct. Nowadays, sizes of files don't play a significant role, I don't see the problem with whole updates. Why isn't the customer happy with whole updates?
Note: If what he wants is dynamic updates, i.e. without restarting the server, then this is anyway a complete different problem, and mostly impossible for production systems in java (but doable during development, with solutions like JRebel).
You can create a Java Program that uses Delta-Sync protocol i.e. Only those files need to uploaded which are updated. If you have used Dropbox then you will understand pretty well.
Dropbox uses Delta-Sync protocol to update file and sync data.
Either way for time being you can use Dropbox by installing on your client (mapping to server's WAR folder) and your local machine and share that folder. Then whenever you change the files in your local machine it will automatically upload and sync those CHANGED (PATCH) files to your client's machine.

Load jar from URL

I've been searching for days but I have not found a clear answer. How would I go about writing a small jar file to give to my users that simply gets a jar file from a URL (with multiple classes in it) and run it. It would be great if the end user never actually has the jar on his computer at anytime. I am doing this as a small security measure.
If the user is going to execute your code, it must exist on their computer. It's just the way it works.
If you wanted to re-write your code to perform most of the work on your servers, that'd be one mechanism to combat piracy, but it does mean that you need to duplicate all the input verification checks: perform them once on the client side, for reasonable response time, and again on your own servers, to ensure that your users aren't trying to use your services improperly.
Another mechanism would be to run a VNC server on your servers, and ask your users to VNC in. The software executes completely on your servers. It is a draconian step though, one your users will likely detest.
I am not sure how you'd go about it, but I know that using Maven allows you to access things without having the jar locally. You can just specify the URL. So maybe look into how they do their repositories.
Another option would be to encrypt your JAR file and write a custom class loader that decrypts it on the fly on client machines. This won't prevent a power user from attaching a debugger to the JVM and examining your byte code, but it prevents the typical user from having access to your code.

Where should a Java web application store its data?

My Java web application (myapp.war) ist deployed by placing it into the webapps direcotry on Tomcat on Ubuntu 10.04.
This application needs to save some data in files. But the user, which is running Tomcat (tomcat6) has no write access to the home directory /usr/share/tomcat6/ and no write access to the current working direcotry /var/lib/tomcat6/, since both belong to root.
So where should a web application store its data? I hope it is not the extracted archive in the webapps direcotry. This one could be deleted very easily by accident. And Tomcat can be configured, not to extract .war files. Then there would be no extracted direcotry.
Perhaps /var/lib/tomcat6/ should belong to user tomcat6 ant this is a bug in Ubuntu?
If the files need not persist longer than the life-cycle of the servlet context, the servlet container provides a private temporary directory for each servlet context, specified by javax.servlet.context.tempdir attribute.
See Servlet Specification 2.3, Chapter 3 Servlet Context
3.7.1 Temporary Working
Directories
The convenience of a temporary
storage directory is required for each
servlet context. Servlet containers
must provide a private temporary
directory per servlet context and
make it available via the
javax.servlet.context.tempdircontext
attribute. The object associated with
the attribute must be of
type java.io.File
Answering his own question, Witek stated /var/lib/tomcat6/webapps/ is writable -- at least on his installation of his version of Ubuntu. On my RHEL 5.2 system /var/lib/tomcat<X> doesn't even exist, so there is no webapps subdirectory writable or not, which leads to my answer.
Q: Where should a Java web application store its data?
A: Wherever you've configured it to store its data.
Make the location configurable, in web.xml as a <context-param> or in a myApplication.properties file.
I can put it where I want on my box, the SysAdmins can put it where they want on the production system.
You can change your mind later.
You don't need symbolic links (which have magically disappeared on me before, breaking the system.)
You can have several sets of test data, and just point the configuration at whichever one you want.
You can put it wherever there's disk space.
You are going to change your mind later.
I think it depends on what kind of data you are dealing with. Most of the time, data goes into the database simply because it is fast and easy to perform a CRUD. If you want to store localized user configuration and you don't care how portable it is, perhaps you can store under user.home, I did that for one of my projects and that works fine. All that being said, I really don't think there's any best practice on this and database seems to be the most obvious choice because you can do whole lot of different tasks against it, and most of them are free to begin with. :)
I found the solution on Launchpad. /var/lib/tomcat6/webapps/ is writable. This means, that the following works:
File myFile = new File("webapps/myfile.txt");
I haven't seen any specific guidance on where you should store that kind of data locally - probably because you'd normally store that kind of data in a database.
When I need to store quick-and-dirty data like that, I store it on a filesystem specifically for that data, to isolate it from other areas where it might get caught up in other activity. Haven't had any issues with the approach so far. Also, if it's important, make sure you store it somewhere where you're backing it up :)

Is it possible to include/embed one Java EE application(war file) inside another?

I have an application which is a portal application and I want to allow other users add their applications to it. In order to do this I need some way to be able to access their applications in mine. Is this possible?
You cannot put WARs inside of other WARs. You need an EAR file to contain WARs, EJBs, etc. One way to implement inter-WAR communication is to package that logic directly in the EAR. It all depends on what you're trying to do.
the way to do inter .WAR communication is by the method
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletContext.html#getContext(java.lang.String)
ServletContext.getContext(URIOfOtherWAR_resource)
I've used this succesfully for doing what you're talking about.
Maybe you need a plugin system or portlet, so your user will not develop a war application but include their portlet inside your application (war). There's a standard : JSR 168 and several implementations :
http://developers.sun.com/portalserver/reference/techart/jsr168/
As others have pointed out, embedding WARs inside WARs is not an option. However, I may have a workaround for you.
Most Web containers I'm familiar with have a "test deployment / auto deploy" mode / capability, where they will automatically deploy an application if the WAR is copied into the right directory.
Your portal application could certainly allow uploading WARs, and it could store the uploaded bytes in a given directory under a given file name. Your Web container could do the rest. You could then link to the new application from your portal, or whatever. All this is relatively easy to do.
However, be advised that this is a horrible idea if there is any security concern whatsoever. You are essentially allowing your users to execute arbitrary code on your server. Unless you completely trust all potential users to be both non-malicious and perfectly competent (think infinite loops), you are asking for a lot of trouble here.

Categories

Resources