汉坤知苑 | “未履行开源许可证义务的专有软件不受法律保护”——GPL抗辩的探讨(上)
作者 | 段志超 鲁学振 蒋海楠 梁杰 汉坤律师事务所编辑 | 布鲁斯
在专有软件中使用开源软件但未履行开源许可证义务可能会影响专有软件权利人的后续行权。我们注意到近期南京市中级人民法院(“南京中院”)在一起涉及开源代码的软件著作权侵权案((2021)苏01民初3229号)中,首次支持了被告的“GPL抗辩”,驳回了原告的侵权主张[1]。根据南京中院在本案中确立的裁判规则,在计算机软件著作权侵权案件中,如果作为原告权利基础的计算机软件使用了GPL开源代码而未履行开源义务,权利人就该计算机软件所享有的著作权将不再得到法律保护,第三人可使用专有软件相关代码而无需承担侵权责任。南京中院在本案中的裁判观点为使用开源软件的企业提出了更高的合规要求,值得业界关注。
本文将以案涉GPL开源软件为切入点,从技术分析和法律适用层面逐步厘清法院对GPL抗辩的审理思路,辨析GPL抗辩的法律依据,并最终就企业合规给出建议。我们对该案件的分析将分为上下两篇,本篇主要从技术层面出发,分析GPL v2及Classpath Exception的适用问题;下篇主要从法律适用的角度探讨GPL抗辩成立的法理基础。
目次
1. 案件简述
2. 何为Classpath Exception?
3. 涉案开源软件是如何与原告的其他代码通信的?
4. 原告软件是否被GPL组件传染?
5. 原告软件是否适用Classpath Exception?
6. 案件之外:企业开源合规启示
一
案件简述
本案中,原告研发了“未来软件—投标文件制作工具”软件,该软件使用了开源软件SharpZipLib(适用GPL v2.0 with Classpath Exception许可证[2])。原告认为被告所开发的“云蜻蜓软件-投标文件制作工具”使用了其软件代码,且被告对代码亦存在接触可能性,因此以软件著作权侵权为由将被告诉至法院。被告认为,原告软件使用GPL组件,整体被GPLv2协议约束;即便认定原被告软件构成实质性相似,被告也因和原告存在GPL许可关系而不构成侵权。此外,原告未以GPL协议开源其代码,属于违反诚实信用原则,不应该支持其侵权诉讼请求。
法院最终认定,原告在主程序中使用了GPL组件,且其使用方式不满足Classpath Exception,原告负有将其软件代码以GPL协议开源的义务但未履行,不支持就相关代码的侵权诉讼请求。原告开发软件的预览程序未使用GPL代码,被告对该部分代码的使用侵犯了原告的著作权,需承担惩罚性赔偿的法律责任。
二
何为Classpath Exception?
涉案开源软件为SharpZipLib,主要功能是实现文件压缩,采用GPL v2.0 with Classpath Exception许可证。根据该许可证要求,如果在使用过程中将SharpZipLib与独立模块链接以生成可执行软件,那么最终形成的可执行文件因满足Classpath例外,而不受GPL协议约束,无需履行许可证义务。
Classpath Exception(也称Classpath 例外)的原文及译文我们摘录如下:
Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination.
As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
将此库与其他模块静态或动态地链接就是基于该库制作组合作品。因此,GNU 通用公共许可证的条款和条件涵盖了整个组合。
作为一个特殊例外,此库的版权所有者允许您将此库与独立模块链接以生成可执行文件,而不管这些独立模块的许可条款如何,并根据您选择的条款复制和分发生成的可执行文件,前提是对于每个链接的独立模块, 您还满足该模块许可证的条款和条件。独立模块即不从该库派生或基于该库的模块。如果您修改此库,则可以将此例外扩展到您的库版本,但您没有义务这样做。如果您不希望这样做,请从您的版本中删除此异常声明。
追根溯源,Classpath Exception并非由SharpZipLib作者首创,其最早出现在为Java程序设计而开发的OpenJDK开源项目中[3]。
Java应用程序的开发需要使用JDK(Java Development Kit)将编写好的源代码文件转换为可供运行的应用程序。在此过程中,编写好的源文件.java在JDK中编译成.class字节码文件,JVM再将.class字节码文件翻译为机器可读的机器码(二进制语言)[4]。在解释器(interpreter)进行解释的过程中,链接(link)操作将会被执行[5],目标程序(开发者自有部分)与被调用的库函数(存在于JDK中)将被链接在一起。
OpenJDK是常用的开源的JDK,早期版本适用GPLv2协议。而根据GPLv2协议,链接将导致GPL 下的传染问题。因此,通过OpenJDK进行源代码编译将导致整个软件需按照GPL协议开源,这对于Java生态而言是极不友好的。针对该问题,OpenJDK的项目作者在GPL v2.0上附加了Classpath例外[6],允许用户通过静态/动态链接方式使用OpenJDK而不履行开源义务。
图1 Java应用程序与JDK的关系
通过对GPL协议设置例外,以促进开源软件传播的情形并不少见。例如,开源软件MySQL即设定了 Universal FOSS Exception,允许MySQL与特定开源软件通过接口通信而不需履行开放源代码的义务[7]。
三
涉案开源软件是如何与原告的其他代码通信的?
回归本案,本案中法院已查明原告软件中就开源软件SharpZipLib调用方式是基于函数的调用,其调用方式见下图所示:
图2 涉案软件与开源软件SharpZipLib的关系
具体而言:
原告的软件分为主程序和预览程序两部分,两部分相互独立;
预览程序不调用开源软件SharpZipLib;
主程序将开源软件SharpZipLib作为动态链接库的一部分而调用,该过程的具体实现方式如下:
(1)原告在自行编写的FutureZR.cs文件中创建函数CompressZip();
(2)该.cs文件和SharpZipLib代码被一同编译为.dll(动态链接库)文件;
(3)主程序运行时调用dll文件;
在实际使用中,为实现压缩功能,主程序调用.cs文件中的CompressZip()函数1次,CompressZip()继而调用SharpZipLib中的函数以实现压缩,并根据执行结果向主程序返回true/false表示压缩成功还是失败。
四
原告软件是否被GPL组件传染?
由于原告软件主程序调用了开源软件SharpZipLib,原被告双方就主程序是否受到GPL v2.0约束未进行过多争辩。法院综合(i)主程序与涉案GPL开源代码存在函数调用关系,且(ii) 涉案GPL开源代码实现的压缩功能系投标文件上传前不可或缺的功能两点,认为主程序与开源代码结合为衍生作品,受GPL协议约束。
就判断GPL协议的“传染”范围,本判决提出,需对软件中原告独立创作的“自有代码”部分和从开源社区引入的“开源代码”进行区分,明确二者的交互关系以及开源代码的功能及其在软件中所起的作用,被传染的程序应当是与原开源软件形成密切通信使得二者高度牵连融合成一体的程序,而非只要有数据交换就会构成传染。(本文概括为“密切通信”规则)
法院的上述“密切通信”规则与自由软件基金会(FSF)[8]提出的判断是否“通过共享或交换复杂数据结构而建立了密切的通信”[9]的判断规则是一致的。FSF还认为“If modules are designed to run linked together in a shared address space, that almost surely means combining them into one program”[10](如果两个模块运行时是在共享地址空间连接在一起的,那几乎肯定意味着它们被组合成一个程序)。也即,FSF认为运行时共享地址空间的两个模块大概率存在“复杂数据结构”的交换,属于 “密切通信”,会引发GPL传染。回归到本案中,主程序采用动态链接库形式调用开源软件,主程序处于共享的地址空间内,一般意义上认为已被传染。
本文认为,涉案软件是否被GPL传染是有探讨空间的。本案的特殊之处在于,主程序函数调用交换的数据并不复杂。FSF也提出“如果主程序动态链接了插件,但是它们之间的通信限于调用插件的‘主’函数及其参数并等待其返回,那么这就是个可以算单一组合程序也可以算两个独立程序的临界情况”[11]。换言之,在虽处于共享空间但数据结构交换较为简单的情况下,主程序是否会被GPL插件传染,FSF是保有疑议的。本文注意到,本判决在在界定传染范围时将该开源软件所起到的功能同样纳入分析“涉案GPL开源代码实现的压缩功能系投标文件上传前不可或缺的功能,因此,主程序系涉案GPL开源代码的衍生作品”。本文认为这种分析路径值得商榷,一者,这种基于“功能论”的观点在GPL文本以及FSF官方问答中没有依据;二来,既然特定的开源软件代码已经被用于所开发的软件中,那么在通常的情形下,它就会承担一定的功能。
五
原告软件是否适用Classpath Exception?
在认定主程序已被GPL v2传染后,南京中院就Classpath Exception是否适用进行了分析,并认定本案并不适用该例外。
双方争论焦点主要集中与本案是否符合Classpath Exception 中“独立模块”、“链接调用”的例外规定,而这两点恰好也是适用Classpath例外的构成要件。
为方便阅读,本文总结相关事实、原被告主张和法院认定如下:
Classpath Exception(原文) | 本库文件的版权所有者允许你将本库文件与独立模块链接以生成可执行文件,而不管这些独立模块的开源许可条款如何……一个独立的模块是一个不从本库衍生或基于本库的模块。 |
原告主张 | FutureZR.cs为独立模块与主程序链接,满足例外情况。 |
被告主张 | SharpZipLib本身提供了用于链接调用的“ICSharpCode.SharpZipLib.dll”,但是原告却自行编写FutureZR.cs以调用SharpZipLib中的函数,并一起重新编译为FZR.dll以进行调用。“FZR.dll”以及相应的源代码属于对开源代码的演绎。原告调用FZR.dll不属于链接调用SharpZipLib,不满足例外情况。 |
法院认定 | 原告自行编写的FutureZR.cs文件与SharpZipLib开源代码一同编译成FZR.dll,并由主程序对其进行调用的方式,不符合“例外声明”中“一个独立的模块是一个不从本库衍生或基于本库的模块”关于独立模块的约定,例外声明对其不适用。 |
• 争议点:本案是否存在Classpath Exception中的“独立模块”,是否以链接方式调用?
本案中,原告主张FutureZR.cs作为“独立模块”与主程序链接满足例外情况,南京中院未予认可。具体地,南京中院认为“通过将自行编写的FutureZR.cs文件与SharpZipLib开源代码一同编译成FZR.dll,并由主程序对其进行调用的方式,不符合‘例外声明’中‘一个独立的模块是一个不从本库衍生或基于本库的模块’关于独立模块的约定,‘例外声明’对其不适用”。
本文认为,原告若将主程序主张为Classpath Exception中的“独立模块”,本案结果或有不同。
具体原因如下:
(1)主程序满足Classpath Exception中的“独立模块”。原告的主程序非基于或衍生(derive from)自开源组件,满足独立模块的概念。
(2)主程序与开源软件的调用满足“链接”调用。前文分析可知,主程序通过动态链接的形式调用SharpZipLib的modified version(即FutureZR.cs文件与SharpZipLib开源代码一同编译成的FZR.dll文件),满足链接调用。该环节可能存在的争议点是主程序并非直接与SharpZipLib链接调用,然而本文认为这并不影响Classpath Exception的成立。一方面,Classpath Exception仅限定是以“链接形式结合独立模块”,并没有限定链接用文件的来源或产生方式;另一方面,即使原告自行编写了.dll文件,.dll以及相应的源代码确如被告所述属于对开源代码的演绎,但这仅是使得这部分代码被认定为衍生作品受GPL开源义务约束,与主程序调用方式是否满足Classpath例外无关。
六
案件之外:企业开源合规的启示
南京中院此项裁判实际上对企业的开源合规提出了较高的要求,在不满足开源义务的情形下甚至可以除却软件权利人请求侵权赔偿的胜诉权。因此,企业的开源合规便显得更为必要。
• 使用GPL组件的合规方式仍未被颠覆
本判决对GPL协议的解读仍然是遵循GPL协议文本,且与FSF官方的理解基本保持一致。
本案中,原告将GPL组件与自由代码在同一地址空间运行,存在整个程序被认定为“衍生自”GPL组件的风险。作为风险缓释措施,原告可采取管道(pipes)、sockets、命令行方式(command-line)等方式以确保自有部分与开源组件在隔离的地址空间中进行通信,将自有代码和开源组件部分加以区隔。增加自有代码独立性,避免被认定为“通过共享或交换复杂数据结构而建立了密切的通信”[12]以致被认定为衍生自(derived from)开源组件。就Classpath Exception而言,考虑到尚不存在官方的解释,其具体合规调用方式存在一定的不确定性,可采用业界较为成熟的GPL的合规方式对相关组件进行处理。
• 建立完整的开源合规体系尤为关键
本案中,原告因未能履行开源协议,其基于自有代码的软件著作权实施受到阻碍。企业通过在内部搭建开源软件合规体系,在软件开发阶段引入开源合规理念,则可通过小成本撬动大收益。通过企业内部成体系的开源合规搭建,可实现对开源软件的引入、更新和退出进行全生命周期的管理。
我们注意到,本案中原告软件所使用的SharpZipLib经历了多次协议的变更,从最初的GPL v2 with Classpath Exception变更到LGPL,再到2016年变为非常宽松的MIT协议。本案被告被认定的侵权行为系从2017年1月1日至2021年8月30日,在此期间,SharpZipLib已有适用MIT的版本[13]。如果原告对其软件中的SharpZipLib开源组件存在监控和管理,则可直接换用MIT版本,届时将不存在自有代码被传染的问题,以致侵权行权受限,难以主张足额损害赔偿的问题。
注释
[1] 参见知产宝——版权案例丨全国首起民事生效判决——GPL抗辩获得法院支持!,https://mp.weixin.qq.com/s/GiMWAdzbqg83OUlwdAQPrQ
[2] https://github.com/icsharpcode/SharpZipLib,SharpZipLib经历过协议变更,由之前的GPL v2 with classpath exception 已经变更为MIT协议。
[3] 参见维基百科词条-GPL Linking Exception,https://wiki.alquds.edu/?query=GPL_linking_exception。
[4] 一倾而尽,什么是JDK,JRE,JVM ---深入分析,https://blog.csdn.net/weixin_38339025/article/details/90313695
[5] chun_soft,Java 代码编译和执行的整个过程,https://chunsoft.blog.csdn.net/article/details/113697528?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-113697528-blog-5904542.pc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-113697528-blog-5904542.pc_relevant_recovery_v2&utm_relevant_index=2
[6] 参见https://openjdk.org/legal/gplv2+ce.html
[7] https://oss.oracle.com/licenses/universal-foss-exception/
[8] FSF是一个致力于推广自由软件的美国民间非营利性组织。它于1985年10月由理查德·斯托曼创建。其主要工作是执行GNU计划,推动施行GPL协议,开发更多的自由软件。GPL许可证最初由FSF的理查德·斯托曼为GNU项目所撰写,FSF分别于1991年和2007年发布了GPL v2和GPL v3。参见维基百科词条“FSF”、“GPL”。
[9] “什么时候一个程序和它的插件会被认为是一个单一的结合在一起的程序?这依赖于主程序如何调用插件。如果主程序使用fork和exec调用插件,那么它们之间通过共享或交换复杂数据结构而建立了密切的通信,这样它们就是一个单一的结合在一起的程序。如果主程序使用的是简单的fork和exec调用插件,并没有建立密切的通信,那么插件就是一个单独的程序。” 参见https://www.gnu.org/licenses/gpl-faq.html
[10] 参见https://www.gnu.org/licenses/gpl-faq.en.html#MereAggregation。
[11] “If the main program dynamically links plug-ins, but the communication between them is limited to invoking the ‘main’ function of the plug-in with some options and waiting for it to return, that is a borderline case.”参见https://www.gnu.org/licenses/gpl-faq.en.html#GPLPlugins
[12] https://www.gnu.org/licenses/gpl-faq.en.html#MereAggregation。
[13] 参见SharpZibLib 1.0.0版(2018年发布)的MIT协议,https://github.com/icsharpcode/SharpZipLib/blob/v1.0.0/LICENSE.txt。
联系作者
段志超
北京市汉坤律师事务所
知识产权部 合伙人
kevin.duan@hankunlaw.com
鲁学振
北京市汉坤律师事务所
知识产权部
xuezhen.lu@hankunlaw.com
蒋海楠
北京市汉坤律师事务所
知识产权部
hainan.jiang@hankunlaw.com
梁杰
北京市汉坤律师事务所
知识产权部
jie.liang@hankunlaw.com
往期热文
(上下滑动查看更多)