简体   繁体   English

Java:在jar文件中只显示一个包

[英]Java : Expose only a single package in a jar file

I'd like to have a jar file in which only the API package is accessible. 我想要一个jar文件,其中只能访问API包。 All the other packages (containing implementations) would not be accessible by another jar (nor by any other class). 所有其他包(包含实现)都不会被另一个jar(也不是任何其他类)访问。

Is it possible ? 可能吗 ?

If yes, how ? 如果有,怎么样?

If you have classes that should not be used, put them into a subpackage named "internal". 如果您有不应使用的类,请将它们放入名为“internal”的子包中。 While this does not prevent others from using the classes, it is a strong indication that they should not. 虽然这并不妨碍其他人使用这些课程,但强烈表明他们不应该这样做。

Example: 例:

my.library.Stuff
my.library.StuffFactory
my.library.internal.StuffImpl
my.library.internal.MoreStuff
my.library.internal.xml.DataStuff

While this is not an actual solution, I would consider it a best practice. 虽然这不是一个实际的解决方案,但我认为这是一种最佳实践。

Currently scheduled for Java 8 (2012?) is JSR 294 . 目前计划用于Java 8(2012?)的是JSR 294 This JSR introduces better modularization language constructs into Java. 这个JSR将更好的模块化语言结构引入Java。

Today, an implementation can be partitioned into multiple packages. 今天,可以将实现划分为多个包。 Subparts of such an implementation need to be more tightly coupled to each other than to the surrounding software environment. 这种实现的子部分需要彼此更紧密地耦合,而不是与周围的软件环境相互耦合。 Today designers are forced to declare elements of the program that are needed by other subparts of the implementation as public - thereby making them globally accessible, which is clearly suboptimal. 今天,设计师被迫将实施的其他子部分所需的程序元素声明为公共部分 - 从而使其在全球范围内可访问,这显然不是最理想的。

Alternately, the entire implementation can be placed in a single package. 或者,整个实现可以放在一个包中。 This resolves the issue above, but is unwieldy, and exposes all internals of all subparts to each other. 这解决了上面的问题,但是不实用,并且将所有子部件的所有内部部件相互暴露。

The language changes envisioned will resolve these issues. 设想的语言变化将解决这些问题。 In particular, we expect to introduce a new notion of modules ( superpackages ) at the language level where existing public access control would apply only within a language level module and access to API's from outside a module would be restricted to API's the module explicitly exports. 特别是,我们希望在语言层面引入一个新的模块概念( 超级包 ),其中现有的公共访问控制仅适用于语言级模块,并且模块外部对API的访问将仅限于模块明确导出的API。

Now I believe the expert group is still discussing the details of this concept. 现在我相信专家组仍在讨论这个概念的细节。 But I believe one thing you might be able to do is this (source: Super Packages in Java 7.0 ): 但我相信你可以做的一件事就是(来源: Java 7.0中的超级软件包 ):

superpackage com.myorg.myApp.model
{
    member package com.myorg.myApp.model.swing;

    member package com.myorg.myApp.model.html;

    export com.myorg.myApp.model.swing.SEmployee;
    export com.myorg.myApp.model.swing.SDepartment;

    export package com.myorg.myApp.model.html;
}

In other words, for a given "superpackage" you can define what is and isn't exported, independent from visibility keywords like public . 换句话说,对于给定的“超级包”,您可以定义什么是导出和不导出,独立于public可见性关键字。

this isn't really possible in Java 6 unless you're using OSGI which I assume you're not. 这在Java 6中是不可能的,除非你使用OSGI,我认为你不是。 what I usually end up doing to hide classes is to use package friendly classes for implementations - but you might still need to expose some class-es if you're implementation classes do live in a separate package. 我通常最终做的隐藏类的方法是使用包友好类来实现 - 但是如果你的实现类确实存在于一个单独的包中,你可能仍然需要公开一些类。

sample: 样品:

package com.example;

public class Service { } assume the API class uses ServiceImpl as it's implementation public class Service { }假设API类使用ServiceImpl作为其实现

now if ServiceImpl lives in the same package you might remove it's public class modifier and it won't be accessible outside the package ... 现在,如果ServiceImpl位于同一个包中,您可以删除它的公共类修饰符,并且它不会在包外部访问...

if it lives in a different package (your case) it needs to be public : 如果它住在一个不同的包(你的情况),它需要公开:

package com.example.impl;

public class ServiceImpl { }

but all implementation details (related classes it uses) from the same package need not to be public ! 但是同一个包中的所有实现细节(它使用的相关类)都不需要公开!

In a "normal" java application that is not possible. 在一个“正常”的java应用程序中是不可能的。 Although in OSGi environment you define which packages are exposed by your bundle (slightly modified jar file) to other bundles and which are private (not visible outside your bundle). 虽然在OSGi环境中,您可以定义捆绑包(稍微修改过的jar文件)向其他捆绑包公开哪些包,哪些包是私有的(在捆绑包外部不可见)。

Why not simply create a jar with the API classes and a seperated jar with implementations depending of the API one. 为什么不简单地创建一个带有API类的jar和一个带有依赖于API的实现的分离jar。 That way, you can distribute your API classes without distributing your implementation. 这样,您可以在不分发实现的情况下分发API类。

KR. KR。

I can see the reason why do you want to do it. 我可以看到你为什么要这样做的原因。 It has always troubled me when I try to use someone's library. 当我尝试使用某人的图书馆时,它一直困扰着我。 There are so many classes which I don't know where to start with. 有很多课程,我不知道从哪里开始。

As far as I can see from most libraries, there is no such a library that try to hide unrelated classes. 据我所知,大多数图书馆都没有这样的图书馆试图隐藏不相关的类。 Although, this is not a solid evidence , it must means there is no way to do it. 虽然这不是一个确凿的证据,但它必然意味着没有办法做到这一点。 Normally, they budle api and the implementation into seperated jar files. 通常,他们将api和实现发布到分离的jar文件中。

However, if you are running your application through OSGi framework, it is possible to bundle your jar file in such way that the OSGi frame can see only the API classes you want. 但是,如果您通过OSGi框架运行应用程序,则可以将OS文件捆绑在一起,使OSGi框架只能看到您想要的API类。 But using OSGi might be a bit of work. 但是使用OSGi可能有点工作。

您可以添加ant-task或maven-jar-plugin配置,根据您的构建工具首选项来包装您需要的组件。

Another solution is to set default access modifier in implementation classes and put them in the same package as interfaces. 另一种解决方案是在实现类中设置默认访问修饰符,并将它们放在与接口相同的包中。 Although its a bit dirty way. 虽然它有点脏的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM