I want to use proprietary, non-OSGi jars in an OSGi environment. For development, we just repackage/export it with the Maven bundle plugin [1]. Problem is, for legal reasons we won't be able to redistribute these packages to our customer, which kills both embedding and repackaging, which are (AFAIK) the only options (see [2]).
Before using OSGi, we had a section in our manual describing how to put these files in a library folder after acquiring them on ones own. Given OSGi rules for resolving classes, this obviously won't work anymore.
Am I correct to assume that the only way to solve this is a legal one, i.e. getting a redistribution license from the packages' vendor (which may be a beurocratic nightmare and impede timely delivery), or am I missing a technical solution?
[1] How can I share non-OSGi libraries between bundles in an OSGi container?
[2] Non-osgi library usage in an osgi application
I would simply add this JAR to the main Java application classpath, using its existing location in a library folder as you have already established. Then you can export the packages you need into OSGi using the org.osgi.framework.system.packages.extra property.
I have seen this requirement too in a commercial project. We ended up adding a special bundle, which on start-up downloaded the needed jars from the relevant sites and added them to our re-export bundles.
So
we have a 3rd-party non-OSGi jar J.jar which we want to use
we add an (almost) empty OSGi bundle with two files
a META-INF/MANIFEST.MF that re-exports all the relevant packages of J.jar
a simple text file - META-INF/DOWNLOADS - that specifies from where we can download J.jar
we have a simple generic OSGi bundle (with a early start-up level) that goes through all installed bundles and checks if META-INF/DOWNLOADS exists. If it does, it downloads the specified jars if not already present.
When the re-export bundle is later started, it will look like we distributed the offending jar... and everybody are happy.
When we needed a new version of the jar, we just released a new version of our jar as we would normally do.. The main problems were how to handle any problems in the down-load process.
Perhaps OSGi Remote Services (distributed OSGi) could be an answer. You would host the OSGi environment that exposes the proprietary lib, and install the rest on the client's machine.
This is quite philosophical. Just what exactly constitutes a distribution of digital content?
(1) We all agree that if the jar in question is included in your installation download, it's a redistribution.
(2) What if the installation program is a thin shell, when it runs, it downloads more stuff from internet. If it downloads the jar from your server, I think most people would agree that this is essentially the same as (1), and it is a redistribution.
(3) What if the installation shell downloads the jar from the owner's server? Suppose it is automated without end user knowledge.
Could anybody really argue that (3) is very different from (2), and it is not a redistribution?
I think it is, for all intents and purposes. We are effectively distributing the jar with our program, how that is done under the hood is not relevant with regard to the spirit of the redistribution license. Whoever gets the program gets the jar along with it, that is a fact.
At least we should contact the author to verify he is ok with it. We must pay due respect to free softwares, do not use them in a way that's against the wills of the authors.
Related
I have seen many interesting (and duplicated) questions here about "sharing or using classes between projects".
I see this as quite practical but the proposed solutions I have read about definitely assume certain prerequisites such as:
shared eclipse workspaces
projects that can be made as dependencies of oneanother
common servers such that classpaths can be added with local urls
While likely acceptable solutions, I am looking for an alternative with perhaps greater flexibility and portability.
I am thinking of learning how to use gradle (or maybe maven, I haven't fully committed to one or the other yet). And from what I understand it may be possible to manage shared classes with one of these dedicated dependency management programs.
Theoretically is this possible? Can I setup a gradle or maven enabled java project to handle and keep uptodate personal classes on a local server or folder on a portable drive or cloud mirror?
The way I understand dependency management at the moment (on a superficial level, I know the devil is in the details) is that for a configured dependency management enabled project, gradle/maven will handle classpath additions and the actual version specific comparison, retrieval and storage (and maybe even compilation is possible but I don't know about this) of JARS from external sources.
Rather than go through the steps to setup classpaths to jars I have to keep current and compiled myself as proposed in many other answers, I am considering creating a dummy project on a server that I can put generic classes which I could then point numerous individual gradle/maven enabled java projects to use. (I think most people would be able to keep them as stand alone classes, but I think I might need to keep them in a dummy project to be developed and debugged in context from a main class. I am somewhat new to java architecture so if the only thing that would make this solution impossible is pointing to a "project" instead of a "library" I can definitely adjust from there. (Assuming I am even applying the concept of the "library appropriately).)
Other info:
I would like this to simplify personal dependency using both Netbeans and eclipse IDE's and work cross platform (but Linux and Windows is what I plan to test it on)
So you're looking for portability, and you don't want to compile your java class that you want to share between projects. And you don't mind a local deployment.
The first thing that comes to mind for me is Git - I'm not sure if Gradle/Maven deal in the gritty underworld of the uncompiled. Composer will pull in git repos for php, so that got me thinking.
If you're happy with one-way sharing of code among projects, Git has submodules that let you do that.
But searching around, apparently there's a git script that goes one step further - Git Subtrees. I also found an intriguing tutorial that will allow you to make changes to common code that you change while working on any particular project that shares it - so obviously be careful - but check it out and see if the Subtrees script might suit your needs.
Actually, I don't see too much sense for dependency management on a "class level". Typically you would bundle your classes in a jar file, which in turn can be considered as a unit with a particular functional range. Such a jar is suitable to be put in a dependency management.
If you are new to such tools, I'd recommend Maven. It is widely used in the Java world and well-integrated in common IDEs. If you stick to its conventions, it will take care of your whole build process from compiling, testing to packaging. There are a lot of plugins available that let you customize practically everything in a simple XML based configuration. You'll have your first project running in 30min and your current project migrated in another 30min.
To share your code with others, you still need a repository where you can upload your Maven-built artifacts to. Depending on your preference there are many possibilities. Shove it to Amazon S3, Maven Central or install your own Sonatype Nexus in your private network.
I have developed a web application which I am going to sell, but I face some security issues because I am going to provide a .war file to client machines and I found .war files can be easily extracted.
How can one provide security for war files to avoid being copied or extracted?
While searching I found Excelsior jet which converts web apps to native code but it's a trial version and I cannot afford its price so I want to know other alternatives.
A web app container cannot deploy an exe anyway. You can obfuscate your classes and maybe write a licensing module. If you prevent users from extracting your war you'll also prevent the container from deployment.
For example, you might use a Java Bytecode Obfuscater such as
yGuard
ProGuard
JODE
As for a licensing module, you may be able to use
this or this question.
The possible way is to
Use code obfuscator
Code in init() or somewhere check for license/access only one host.
Another option is to code your own classloader and implement it in modified web container
Suppose I have a Java code which depends on lots of libraries.
I use ClickOnce to deploy the application on the clients machine.
When something changes in the code I don't want the dependant libraries to be redeployed.
Current organization is the following:
when the code is changed, it is being compiled, version number increased and lots of jar files within one folder are copied to the distribution folder with the appropriate version. Later the application manifest chooses the latest version and deploys the application COPIYNG all the libraries.
Main question: Is it possible to separate the libs which never change with the custom code?
I'm quite new to ClickOnce, searched for MSDN and Googled a little, but failed. So links to the ClickOnce dependency management tutorials will be highly appreciated, thanks!
P.S. ClickOnce for Java code sounds ugly but it was strict political desicision, sorry.
I have a lot of small-ish Java command-line apps that have to use a vendor set of jars to make their connection to the servers, and while writing these apps has been pretty easy, maintaining them is turning out not to be.
I built them using Maven and some templates that gave me a pretty quick turnaround on development time, but these are all standalone command-line apps so far.
The pain comes from the updates to the vendor servers. Whenever it happens, it forces me to recompile all of these applications with the new jars in play, otherwise I'd get SerialVersionUID Exceptions and borked apps.
What I'm considering
I was thinking that it would be possible to use Maven to generate the app and then throw it in an app server with the server providing a set of shared vendor .jars in whatever /shared classpath it provides. That way I could just update the .jars, restart the server, and everything will likely continue without error.
However, I'm not sure what is required to get that working. They aren't .war's, and most of these apps use other .jars besides my code that isn't usually shared.
Questions
What kinds of deployments work like this?
Are there other ways to do this that I'm missing?
Any tutorials, frameworks, etc., that would make this simpler?
I could just share from my experience. We have 3 ways of overcoming this at the moment. The first way, was our old way, which we still use.
Create a base project which we link to with all our external JARs. The user project when compiled/deployed checks for a newer tag of the base project than it is currently using, and if there's a newer tag, it will fail and force the user to check for the updates and recompile. The benefit of this is that at compile time you can check for new jars, and we get a list of what changed, and reload the jars. In our IDE we can quickly see if anything changed from the API - it has been known to happen, then we can fix and recompile. Also because we're aware of the changes, we can read the changelogs and see if any of the changes affect us, and we then retest parts of the application that depend on these libraries.
We use Maven, but instead of the public repositories, we maintain our own repository, where we only move a library into our local repo after it has been tested - so no surprises for us.
This method is unique to a Tomcat deployment, but we also load libraries via the Context using a classloader. It's not my favorite way to load external jars, but this one works without a deploy. Of course since the compiler isn't there to help you, the new jar can not be 100% compatible with your code, and you can end up with some runtime NoSuchMethodError or ClassNotFoundException expections.
I might be misunderstanding your situation, but if the interface you use in the vendor libraries does not change between versions, couldn't you just keep the jar-files in the classpath of your command-line applications and thereby just overwrite the vendor files when necessary? In that way you would only need to recompile when the interfaces change in a way to break your code?
I have a large, growing OSGi application with a number of bundles. I am curious to know the best way to manage this type of application. Currently, I am using Eclipse and Maven, but although this is great for building bundles (via maven-bundle-plugin), as of now it has not been easy to manage the entire application.
What I would like to do is either have ONE run configuration or ONE pom.xml that can be launched and the entire application/project be built and launched. Also, I would like to have something that would be good for debugging.
I have heard of PAX Construct and have it installed in Eclipse, but so far it has been of little help (maybe I'm not using it correctly).
I am sure there are people out there with large OSGi applications that are being managed correctly. Any advice that could be shared would help tremendously.
Thank you,
Stephen
A run configuration is possible via Pax Runner. It lets you choose OSGi platform implementation, specify profiles (pre-packaged sets of bundles for some role, e.g. web, log, ds, etc.) and has good provisioning support, for instance it can load bundles from Maven repository. As a result, you can have a run configuration like
--platform=felix
--log=INFO
--profiles=scalamodules,ds,config,log
mvn:com.my/bundle/1.0.1-SNAPSHOT#update
# other bundles
In case your application is very large or you have different applications, there a way to create own profiles as well.
Well...
It all deopends on what do You mean by "managing" the application.
For dev time launching, building and debugging - Eclipse IDE should fit the bill just perfectly.
Maven... I can't speak for it, as I've never used it myself.
We have a pretty large eclipse based application (several, actually) and on the dev side of things we are not using anything special besides the Eclipse and it's integrated SCM.
In the cc build server, we also use headless eclipse to do the building and packaging.
Now the setup of the workspace has gone a bit out of hand of late with all the dependencies and intermediate build steps, so we are investigating Buckminster for managing the materialization of target platform and workspace resources.
If that works out, we'll probably move to building with Bucky as well - it sure looks promising.
(I do not have any experience with PAX, but at a glance, it looks promising as well...)
i'm quite new to OSGi but,
wouldn't it be possible to use OBR-service in such a way that
you would have one OBR repository file which needs the bundles
and let the OBR-service figure out the dependencies and populate your OSGIhost for you?
This area I think has very poor support at the moment. OSGI doesn't really define anything about deployment or packaging so its up to other frameworks (e.g. Eclipse) to come up with their own way of doing it.
If you are building an RCP (Eclipse base) application, then the eclipse systems do all this stuff, right down to creating exes etc. However builds are mainly done on the Eclipse workspace, headless builds are trickier. The Tycho project is trying to make this more sensible by joining the Maven and Eclipse build cycles, however it is still focussed on RCP applications rather than generic OSGI.
If you not doing RCP, which is my situation as well, then you probably have to roll your own solution, as I haven't found any general solution. Here's an outline of what we do:
We define one POM project that lists all the bundles that are contained in your application. All this project does is list the references - lets call it the 'bundle-list' project.
Then, we use pax provision to run the project in development mode. This is achieved by making the 'bundle-list' pom the parent of the provisioning pom of the pax project (usually in the 'provision' folder). Then, when you start pax, it uses the list of bundles from that project to start OSGI. The bundle references in the 'bundle-list' project have to be marked as 'provided' scope for this to work.
Then, to create a distribution, we have another project. This project also has the 'bundle-list' project as its parent. This project uses various plugins to create a distribution, including downloading the bundle jars. The distribution includes scripts that start up OSGI, but these are hand written, there's no pax systems here.
This works well for us to keep the list of bundles in one place, but there's still a lot of hand written scripts, and there are issues sharing configuration between the two systems - e.g. config files, bundle start levels etc.