How to mark that a lgpl library is modified [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I am using an LGPL library in my code. For my needs, I need to modify the code in the library.
How do I mark the jar file that it contains modified code? Some txt file in the jar? In that case, what do I write in the txt file?
I will include in the license agreement that we are distributing a modified version of the jar, but my question is about marking the jar itself.

The short answer: Avoid the issue
If you have fixed a bug, or added a feature why not submit it back to the original authors by way of a patch? If they accept it, the next version of the library will include your fixes and you won't need to worry about shipping a modified library! Sharing your changes/improvements to the library is the essence of the license, temporarily using a slightly modified version of the library while you are waiting for your submitted improvements is fairly common practice (see stuff about vendor branches). Becoming part of the development community means you are no longer shipping a 'modified' version of the library, but actively contributing your improvements to the original library for the common good.
The long answer: LGPL Version 3.0
From version 3.0 of the LGPL itself:
Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version:
a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
As long as you comply with the rest of the license text, you don't necessarily need to 'mark' the jar itself, with a text file or otherwise. For compilation reasons, you could follow the suggestion of extraneon and use a slightly different jar name. You could use a vendor branch or something to maintain the differences between your modifications and the original library. Here you are 'forking' the project, creating your own derivative work - the essence here is to share your changes and improvements to the source with the world.
The long answer: LGPL Version 2.1
From version 2.1 of the LGPL itself:
You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
In essence you must say: Hey here is library 'foo', a modified version of library 'bar', here you can use my version of library 'foo' - it too is available under LGPL2.1. The prominent notices are also usually performed at the beginning of your modified source files in the LGPL license comment block. Again your are forking the library.

Give the jar a different name. The classes inside will have the same names, so code depending on it won't have a problem finding it (if the new jar is on the classpath).
It's of course always wise to document your changes by adding some info in the manifest file, and perhaps also a changelog file in the jar itself.

Related

Why aren't Java package vulnerabilities fixable with a single patch?

I have zero experience with Java, but when trying to understand a certain "apocalyptic" vulnerability, I ended up with a fundamental question about imports in Java, so please bear with me.
My question is, as given in the title, why a Java package can not be updated with a single central patch.
For comparison, two hypothetical diametric cases that I think I understand reasonably well:
If, say, a python library had some vulnerability, then it should suffice (on well-maintained systems that use centralized libraries located on PYTHONPATH) to update that single library and any code that imports it should, in general, be fixed.
On the other hand, if a C library had a vulnerability, then it would be necessary to replace every single binary whose source includes the vulnerable library with a patched binary.
Now, as far as I could tell, Java is actually closer to the former category of languages, where external imports are not included in compiled sources.
If this is the case, then why can't a single patch be applied to fix an entire system (au contraire, our IT department forwarded a gigantic list of software for us to check individually)? Is it because of multiple decentralized copies of identical libraries being installed, or is there some other reason? Or am I misunderstanding the issue?
Java applications themselves are separate processes. In principle, all these processes can use different VM's. This is often the case for larger applications, which are tested against a specific VM. In principle, Java runtimes (J2SE implementations) should remain as compatible as possible with each other, but it is certainly possible for developers or libraries to muck this up, e.g. by using "Sun" inner classes or by assuming things not specified for the API calls. Personally hate these kind of J2SE inclusions; I'd rather have applications that are created to remain compatible.
Smaller applications usually just run on one of the installed JRE's. However, they usually still need additional libraries or components - say, for instance, Log4J from Apache. These are often offered as separate .jar files (or "artifacts" in Maven speak). These libraries may also get updates; there is however not a common way of updating these on most systems; there is no single "application" set of shared libraries although it is certainly possible to create one. On Linux for instance there may be a set of libraries in /usr/share/java (by version, with generic names pointing to the latest one).
Many web applications - I those running on a specific application server such as Tomcat, Glassfish etc. do share a common "classpath", where application specific .jar files are put in specific folder. In that case an update of a library in the shared folder will affect all applications.
Java has had a framework for specific class-loaders, and in principle any framework can define their own set, so where the libraries are stored can depend on the framework. Java is very flexible and doesn't really have one single way of handling applications.
All this has previous little to do with import statements. These are just use as a shorthand notation, basically. You might as well use java.util.List as import java.util.List followed by List further in the code. Class files contain references to other classes (etc.), and those are resolved (found and loaded) at runtime; see the description from Oracle here.

FHIR Migration and Backward Compatibility

As system implementors, we face a dilemma when we migrate from one version of FHIR to the next. We started off using FHIR 0.0.81 and then moved to SVN revision 2833 on Sept. 10, 2014, to incorporate a bug fix. As suggested, we downloaded the Java code from SVN trunk and followed the directions on the FHIR Build Process page.
FHIR 0.0.82 Incompatibilities
Now that FHIR 0.0.82 is available, we want to upgrade to a released version. After downloading 0.0.82, however, we noticed that several resources such as Appointment that were in trunk rev2833 are not in release 0.0.82. This leads to our first questions:
What does trunk contain if it does not contain the latest code destined for the next release?
Should anyone ever use what's in trunk?
Is there a release branch from which 0.0.82 was created?
Trunk Incompatibilities
Since our code has dependencies on resources introduced on trunk but not included in 0.0.82, we have to continue to checkout FHIR directly from SVN. On Oct. 21, 2014, we downloaded SVN revision 3218 Java code. When we integrated that code into our system, we discovered numerous compatibility issues. Here are some of them:
Various Enum values changed from lowercase to uppercase, including Patient.AdministrativeGender and HumanName.NameUser. Though conforming to the Java naming convention is a good idea, changing fundamental data types breaks compilation.
Method names have changed, also resulting in compilation errors. We also discovered that simultaneous name changes occurred. For example, in the HumanName class the old setTextSimple(String) is now setText(String), and the old setText(StringType) is now setTextElement(StringType). Both the name and parameter type of setText() has changed, making migration error prone because one has to decide at each use whether to change the method or its parameter.
The ResourceReference resource type has changed its class name. In the FHIR model package alone, 859 occurences of ResourceReference in 61 file were affected. This does not include changes that rippled through other FHIR packages, or changes that will ripple through our application code and our database schemas.
We notice several new resources in the rev3218 trunk code, including NewBundle. Previously, we had suggested that bundles should be resources, so it's great to see this change. Since trunk is not backward compatible with the 0.0.8x releases, however, I'm not sure if we will have to support the both the old and new way of parsing and composing JSON and XML bundles.
To put a finer point on things, it's important to recognize that some of the above FHIR changes not only affect compilation, but could easily introduce subtle bugs at runtime. In addition, the FHIR changes could require database schema changes and data migration in some applications. For example, our application saves JSON resource streams in a database. Something as simple as changing an enum value from "male" to "MALE" requires migration utilities that update existing database content.
Going Forward
We are investing heavily in FHIR; we want it to succeed and to be adopted widely as a standard. In order for that to occur, issues of backward compatibility and version migration need to be addressed. In that vain, any light that can be shed on the following question will move us all forward:
What is the purpose of the 0.0.8x line of code? Who are its target users?
What is the purpose of the code in trunk? Who are its target users?
Will users of 0.0.8x ever be expected to migrate to the trunk codebase?
If so, what migration strategy will used to address the many incompatibilties between the codebases?
What is the deprecation policy for code in each codebase?
What level of backward compatibility can be expected from revision to revision in the code in trunk?
Is there a FHIR roadmap that system developers can use to plan there own development cycles?
Thanks,
Rich C
My apologies for not documenting the way versioning affects the Java reference implementation more. I'll do so. I will assume that you are familiar with the versioning policy here: http://hl7-fhir.github.io/history.html
There are two versions of FHIR extant at the moment. The first is DSTU 1. This is a fork in SVN ("dstu1"), and is only changed for significant bug reports. The reference implementation there is maintained and backwards compatible. The second version is the trunk version, in which we are preparing for the second DSTU release. The svn is highly unstable at the moment - changing constantly, and we are sometimes reversing changes several times, as we consider various options in committee. Further, there are several large breaking changes between DSTU1 and trunk, and more are coming. So you should not expect that switching between DSTU1 and trunk will be painless. Nor should implementers be using trunk unless they're really bleeding edge (and tightly connected, e.g. the implementers skype channel). When trunk is stable, and we think it's worth releasing an implementers beta, we update the versions and version history, and make a release here: http://hl7.org/implement/standards/FHIR-Develop/ and release a maven package for that version.
In the trunk, since there are many changes being made, we also changed the constants to uppercase, and flipped the way that get/set properties were generated. Agree that this has a price, but there was already a price to pay for switching from DSTU1 to trunk. And when I do a beta release (soon, actually), I'll update the Java reference implementation number and so forth. Note that the Java constants went to uppercase, but the wire format constants did not change, so stored json streams are fine (though they are broken by many other changes in the specification)
Given the scope of the changes between DSTU 1 and trunk (there is no list of these yet, I will have to prepare that when I update the beta), you should expect extensive rework for the transition. Presently, I maintain a single source that implements a server for both (in Pascal, http://github.com/grahamegrieve/fhirserver) but I suspect that this approach is about to get broken by the change the NewBundle represents.
So, specific answers:
What is the purpose of the 0.0.8x line of code? Who are its target users?
Supporting users of the existing DSTU1 specification
What is the purpose of the code in trunk? Who are its target users?
preparing to be DSTU 2. It should start to be more stable in a few weeks time - once we started making backwards incompatible changes, we are trying to get as many of them done as possible now
Will users of 0.0.8x ever be expected to migrate to the trunk codebase?
yes, when DSTU 2 is released, or at least, when we start having connectathons on the trunk version preparing for DSTU2 (first one is planned for January)
If so, what migration strategy will used to address the many incompatibilities between the codebases?
There's going to be a lot of re-writing code. We may release xml transforms for migrating resources from DSTU1 to DSTU2 when it is finalised, but that may not even be possible
4a. What is the deprecation policy for code in each codebase?
DSTU 1 is extremely conservative. trunk will settle, though we will never guarantee stability. The beta releases will be point in time releases of these.
What level of backward compatibility can be expected from revision to revision in the code in trunk?
None, really, at the moment.
Is there a FHIR roadmap that system developers can use to plan their own development cycles?
Well, in addition to the version policy referenced above, there's this: http://www.healthintersections.com.au/?p=2234 (which was for you, no?)
As a supplement to Grahame's response: On the Documentation tab of the spec, there's only one bolded link - Read Prior to Use. That page that tries to make clear that the DSTU release promises neither forward nor backward compatibility. It can't - the whole purpose of DSTU is to gather implementation feedback about what sort of substantive changes are needed to make the standard ready to be locked in stone when we go normative. If we promised forward and backward compatibility in DSTU, then we'd be stuck with whatever decisions we'd made during the initial draft, whether they turned out to be good ones or not.

Can the Java Metro stack be used in commercial closed source projects?

I'm currently looking at the Metro stack on my search for a nice SOAP web service stack that should be used in a closed source project, but i dont fully understand metros license terms that can be found here:
glassfish.java.net - license
So my questions are:
Can the Java Metro stack be used in closed source projects?
If yes - what am I allowed to do with the libraries if I want to keep my own code closed source?
Best regards
After some more research I found that the Netbeans framework is licensed with the same construct (GPLv2 and CDDL) and luckily the guys at Netbeans took the time to explain the how what and why a bit:
Netbeans license FAQ
Here is what they say about dual-licensing:
Dual-licensing is the practice of distributing identical software under two (or more) different sets of terms and conditions. When software is dual-licensed, recipients can choose which terms under which they want to obtain the software. The two usual motivations for dual-licensing are business models and license compatibility. [...]
Additional search for details about CDDL brought me to this site containing a nice summary:
why the dislike for cddl
Here is one of the parts relevant that is to my question:
CDDL is a file-based license. This means that if you make any changes to CDDL-licensed software, any existing files that you modify need to remain under CDDL, but any new files that you create can be under whatever license you want as long as that license isn't incompatible with CDDL.
Conclusion (note that I'm not a lawyer and this is no legal advice - just my personal interpretation based on the available information):
Metro seems to be useable for commercial closed source projects but changes to the existing source have to be made available under the same license as the original source.
So as long as one is just using the libraries the own source code can be kept completely closed source.
At least if CDDL is chosen.

Trimming my Java Project

I am currently working on a project that utilizes the jfreechart library. I am currently using the jar file for this library by adding it in my build path. However I do not need the entire functionality of the library. I would like to carve out only those sections of the library I have used my code and obviously the dependent code.
My ultimate aim is to reduce the size of the project. I have to meet some size targets and using the entire 7 mb jar library is not an option.
I wanted to know if there is a way to do this apart from manually checking for dependencies?
I would ideally like to apply any suggested method to the jar file of the library but if there is a convenient way to detect unused code in the source code I am willing to import the source code into my project.
I apologize if my request is a repeat or a stupid question.
Thanks,
Sudipto
Unfortunately, you can't do this without (arguably) violating the JFreeChart license.
JFreeChart is licensed under the Lesser GNU Public License, and one of the tenets of that license is that the end-user should be free to modify or replace the licensed software embedded in your software. If you cherry-pick classes from JFreeChart and incorporate them into your JAR, you make it difficult for your users to exercise their right to replace the embedded JFreeChart classes. This is certainly against the spirit of the LGPL.
For more details, refer to the GNU LGPL and Java page.
If you want to do this kind of thing with JFreeChart, you will need to get permission from the copyright holder. If your supervisor is really keen to keep the download size down, a large cash donation to the JFreeChart project might help them come around to his way of thinking. (Disclaimer - I have no connection whatsoever to the project.)
This can indeed be hard to determine because execution paths of an application can differ per run. However there is the Instrumentation interface which can show you all the classes currently loaded by the JVM. That should give you an idea which classes to keep. As long as you have run all the possible outcomes of the application.
Generally speaking, this is of course a bad idea, but since you've asked...

How to pack java project?

I have made a java project and want to deliver it to a client but I don't want to deliver it as a jar file as the client can see the source code easily by unpacking the jar file.
How can I pack my java project so client cannot look at the source code or cannot change the source code?
One more thing, Can I integrate a key functionality so that client can only access that software by first registering it with the key provided by me?
Second, can I integrate another functionality through which the software can run only on a single machine through that key?
Remember, the software should still have the cross-platform functionality and if it is not possible then how can I made it for Debian Linux as I have made it on Windows.
To your first point. Why not only jar up the class files? These are in byte code so the client will not be able to view the source.
As to providing a key. This can be done and there are libraries that allow this, but be careful as , to my knowledge at least, there has yet to be developed a DRM system that hasn't been cracked. and most users do not like software restricting what they can do. The same point applies to your third question.
Obfuscators
There are some simple things you can do to make it a bit difficult for a client to get hold of your source code and to enforce per-host (etcetera) licensing. For example, obfuscators make it harder to reverse engineer bytecode files, and license managers support a range of restrictions based on the "keys" that you generate and supply.
The problem is that none of these protect you against someone who is determined to subvert the restrictions are trying to impose. For example, no obfuscator can prevent someone figuring out where your code calls a license manager, and once they know that they can modify the code to subvert any license checking.
Short of locking down the entire execution platform (e.g. turning of the client's ability to run debuggers, read physical devices and so on), there is nothing you can do about this.
A more viable strategy is to include appropriate protections in the software license that you require the client to sign. And accept that there is a risk that you may need to take clients to court if they willfully violate the license agreement.

Categories

Resources