On 06/02/2015 6:32 AM, Curtis Rueden wrote:
Hi Ron,
Why not just mock the classes and have the mock classes take the
appropriate actions when they are called by mistake.
To clarify my earlier comments: I like your solution here, and agree that
it would work well in this circumstance. It gives more control than my
suggestion to catch NoClassDefFoundError, and would only cause problems if
there might be a downstream project that legitimately wants to include the
real B for any reason.
But wouldn't they just remove the mock B jar and replace it with the
real "B" jar at deployment or just not install it if the real "B" is
already present.
I am assuming that Mark is delivering a product that support both a
run-time with encryption and a run-time that supports non-encryption
operation.
I am not completely clear on the business arrangement between Mark's
company, the consumer and the supplier of the real "B" so installation
details are open to discussion.
I was trying to suggest something that would remove the concerns from
the development side and shift it to the product packaging or
installation phase where different "B" jars would be present at run-time
depending on what the end-user wanted/purchased.
I would suggest 3 versions of "B"
1) Full package from the third party providing real encryption (perhaps
purchased and installed separately by the consumer)
2) Consumer version of the non-encrypted "B" that fails in an
inoffensive way if called by mistake (as an optional install component
if the consumer does not have the real "B").
3) Developer version of the non-encrypted "B" that fails with loud
screaming, personnel insults and threats of total annihilation (and lots
of logging) when called by mistake, to be used in testing the
non-encrypted operation.
Ron
My comments were mostly orthogonal to yours, in that:
A) I think the A project should declare B as an optional dependency, not
provided; and
B) I do not think the A project should use reflection to access B, but
rather let the compiler do its job, and catch ClassNotFoundException to
handle B being missing.
But neither of those comments are really under the control of Mark's
project. I just mentioned them because he asked why A wasn't using
reflection to access B.
Regards,
Curtis
On Thu, Feb 5, 2015 at 1:11 AM, Ron Wheeler <[email protected]>
wrote:
Why not just mock the classes and have the mock classes take the
appropriate actions when they are called by mistake.
Seems easier to manage and you just provide the right jar at run-time as
part of the install or deploy.
The developers don't have to worry about dependencies and maven works
nicely.
You could have a testing mock version that jumps up and down when it is
called by mistake so that the programmers know that they missed the test
for the option.
Ron
On 04/02/2015 5:32 PM, Curtis Rueden wrote:
Hi Mark,
I'm working on a project which has an "optional" transitive
dependency. That is: we depend on someone else's artifact (let's call
it A), which itself depends *in some circumstances* on a third
artifact (from a third source) which I'll call "B". That is: if you
never trigger a certain feature of A then it doesn't really need B. A
expresses this by making B a dependency with <scope>provided</scope>.
Wouldn't it make more sense for A to declare the dependency on B as
"<optional>true</optional>" rather than abusing the provided scope?
http://maven.apache.org/guides/introduction/introduction-to-optional-and-
excludes-dependencies.html
I think that A should use Class.forName to probe for B and (if not
found) gracefully explain why it cannot perform the requested
function.
I have historically had a lot of trouble with things done that way. The
problem is that Class.forName is very easy to mess up when custom
ClassLoaders are in use. Personally I think it is better to use a
compile-time dependency, and write the actual direct Java code, catching
ClassNotFoundException in the appropriate places to handle the situation
where the dependency is not present at runtime. Then you lean on the
compiler, and avoid subtle reflection-related bugs and problems. Since the
dependency is declared as <optional>true</optional>, you do not infect
downstream code with the dependency in every case -- instead, people can
choose for themselves whether to use it.
We are thus faced with a choice: declare a transitive dependency as if
it were a direct dependency, to support an unusable feature, and leave
notes all over our POMs to explain why dependency:analyze is wrong and
you should not remove this dependency; or keep explaining to people
why they get NoClassDefFoundError when processing some of their files.
Could you work around their design issue by catching NoClassDefFoundError,
and handle the error in a more appropriate way for your users?
Regards,
Curtis
On Thu, Jan 22, 2015 at 10:48 AM, Mark H. Wood <[email protected]> wrote:
I'm working on a project which has an "optional" transitive
dependency. That is: we depend on someone else's artifact (let's call
it A), which itself depends *in some circumstances* on a third
artifact (from a third source) which I'll call "B". That is: if you
never trigger a certain feature of A then it doesn't really need B. A
expresses this by making B a dependency with <scope>provided</scope>.
I feel that this is an abuse of the dependency mechanism, and that
optional dependencies should not be declared to Maven as dependencies
at all. I think that A should use Class.forName to probe for B and
(if not found) gracefully explain why it cannot perform the requested
function. What do you think?
The feature in question is decryption of a file, which is triggered
when A recognizes an encrypted file, and that is out of our control.
Decryption requires key material, and in our application there is no
reasonable opportunity to provide it, so we can't actually make use of
the decryption function. We are thus faced with a choice: declare a
transitive dependency as if it were a direct dependency, to support an
unusable feature, and leave notes all over our POMs to explain why
dependency:analyze is wrong and you should not remove this dependency;
or keep explaining to people why they get NoClassDefFoundError when
processing some of their files.
--
Mark H. Wood
Lead Technology Analyst
University Library
Indiana University - Purdue University Indianapolis
755 W. Michigan Street
Indianapolis, IN 46202
317-274-0749
www.ulib.iupui.edu
--
Ron Wheeler
President
Artifact Software Inc
email: [email protected]
skype: ronaldmwheeler
phone: 866-970-2435, ext 102
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
--
Ron Wheeler
President
Artifact Software Inc
email: [email protected]
skype: ronaldmwheeler
phone: 866-970-2435, ext 102
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]