I have created a sealed jar, but I don't see difference compared to using a non-sealed one.

  • What tests I can perform to verify the jar is sealed?
  • What reason we could have to prefer using a sealed over non one?
  • Will a sealed create any trouble to users of my projects?
  • 3
    I have reworded the title and the primary question in the post (mostly minor wording tweaks at this point). It should be a bit better now. – user40980 Feb 15 '15 at 1:08
  • 1
    Did you read Sealing Packages within a JAR File? This applies both to individual packages and entire jars. – user22815 Feb 16 '15 at 4:33

You can test that a jar is sealed by defining a class to exist in a package used in the jar file. If the jar is sealed, all packages are normally sealed, else you can seal them on a per-package basis. The class you create should then try to access protected or default members of a class in that package.

For example, if the jar has a class com.example.Widget where the package com.example is sealed and Widget has protected/default members, create a class com.example.Test that attempts to access those members. This should fail.

The reason for sealing follows from a description of how to test it: you want your code to be self-contained and users of the jar should only use public members. Packages are not required to be unique across jars (and bin folders in your IDE) used by a program. You are able to define a class in the same package as in a jar and access protected/default members that might cause problems. Often, default visibility is used as an analog to C++'s friend keyword by allowing other classes in the same package the ability to perform actions that are only safe because the same programmers work on both classes and understand their internals. Perhaps a default visibility method forgoes some bounds checking in the name of performance, with the understanding that client code will never access it. For example, the String class in Java has a few of these types of methods since String handling has to be lightning-fast because a large amount of code relies on it. BigDecimal is built on top of BigInteger and uses default access to optimize a few operations that other users of the class ought not to use.

TL;DR: Classes in the same package might access non-public members of each other for performance or simplicity. This access might not check invariants and preconditions. One can put classes in the same package in multiple locations in the classpath. Sealing a package or jar restricts client code from accessing these methods, because it might break stuff otherwise.

This will not cause any problems for users of the jar. The classloading mechanism that accesses resources (e.g. class files) in jars fully supports sealed jars and packages.

Related reading: Sealing Packages within a JAR File

  • so if I want Widget to be fully extendable, I must not seal the jar as protected members will be inacessible? or may be create another jar that is not sealed for it right? in other words, like the 3D JMonkeyEngine, they will not seal their jars I think (and I must care to not seal it too when distributing, but I will see my very project not working if it is sealed I guess, because I extend and access protected members). – Aquarius Power Feb 16 '15 at 22:12
  • Also, I wanted to prevent protected members access from classes on the same project; in this case I guess I would need to create another small project, and use its sealed jar on the main project right? or there could have another way? – Aquarius Power Feb 16 '15 at 22:13
  • I read also about a SecurityException in case of we try to "override a class" of a sealed package. – Aquarius Power Feb 16 '15 at 22:21
  • 1
    From the linked article: "Packages within JAR files can be optionally sealed, which means that all classes defined in that package must be archived in the same JAR file." This is merely about restricting the package specification of a class, which has impact on default/protected members which are accessible by other classes in the same package as I describe in my answer. This is orthogonal to inheritance, meaning you can extend classes in sealed jars and you can access protected members that way. – user22815 Feb 16 '15 at 22:24
  • If you want a class in a sealed package not to be extended, make it final. If you want it to be extended inside the jar but not outside... you need to start looking at default visibility classes, interfaces, factory methods, etc. which are outside the scope of this question. – user22815 Feb 16 '15 at 22:25

To answer your second question, we seal our Jars as a security measure, as this prevents a form of code injection where additional classes are added to our code base at run-time.

We have a certain amount of reflection in our code where objects are created based on user input. The code that creates these objects will only allow classes from fixed package names to be instantiated.

By sealing the jars that contain the classes we want to users to be able to create, there is no way the user could create new potentially dangerous classes and have our software instantiate them at run-time. Unless the class is in the correct package, our code will not load it, and sealing the Jars means that only the classes we wish the users to have access to are accessible.

If our Jars were not sealed, the user could potentially add new classes that could be instantiated. This would be a security risk.

TL;DR: By sealing your Jars, you can prevent one type of malicious code-injection.

  • so basically we would need to hardcode (string constant) the access to the newly instantiated classes to grant they are on the correct package? I wonder also if that could interfere with jrat profiling? – Aquarius Power Feb 22 '17 at 21:25

Your Answer

