Re: Remove Artifact Commons-Lang Dependency?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: Remove Artifact Commons-Lang Dependency?

Mark James
Karl, I'd like to embed Maven version string comparison in my JAR so my users
don't have to install both Maven and Commons-Lang. But I'd like to do this in a
way that my JAR isn't an order-of-magnitude bigger.

I've found I can embed just

org.apache.maven.artifact
org.apache.maven.artifact.handler
org.apache.maven.artifact.metadata
org.apache.maven.artifact.repository
org.apache.maven.artifact.repository.layout
org.apache.maven.artifact.repository.metadata
org.apache.maven.artifact.resolver
org.apache.maven.artifact.resolver.filter
org.apache.maven.artifact.versioning
org.apache.maven.repository
org.apache.maven.repository.legacy.metadata

as long as I make the small mods I posted to remove the Commons-Lang dependency.

Should I keep these mods as a custom fork, or would they be a worthwhile patch
to the distribution?

Mark

On 26/11/2019 05:01, Karl Heinz Marbaise wrote:

> Hi Mark,
>
> can you tell us on which part of Maven you are referencing? Or do you
> reference your own project?
>
> Maven Core ? a particular plugin ?
>
> Kind regards
> Karl Heinz Marbaise
>
> On 25.11.19 03:08, Mark James wrote:
>> Hello,
>>
>> Is there any chance of removing the dependency of Artifact on Commons-Lang?
>> Something nine times bigger is pulled in just to reference the String utility
>> functions isNotEmpty, notBlank, and isNumeric.
>>
>> I understand the advantages of libraries, but this comes at more of a cost in
>> Java because common Java libraries are less likely to be on the system than
>> native libraries, and so must be either specified as a dependency (that must be
>> downloaded and added to build and class paths), distributed with the using JAR
>> (requiring an installation expansion), or embedded into using JARs (defeating
>> the space-saving advantage). Semi-automated dependency resolution probably makes
>> this easier, but many such as myself aren't familiar with it.
>>
>> I'd like to be able to distribute my package as a single JAR, with Artifact but
>> not Commons-Lang embedded. But this currently needs the following changes:
>>
>> 1. Replacing StringUtils.isNotEmpty in DefaultArtifact with a not-null +
>> positive-length test.
>>
>> 2. In ArtifactUtils.notBlank, replacing
>>
>>          Validate.notBlank( str, message );
>>
>>      with
>>
>>          for (int i=0; i < str.length(); i++) if
>>          (!Character.isWhitespace(str.charAt(i))) return;
>>          throw new IllegalArgumentException(message);
>>
>>      or, using Java 8 code,
>>
>>          if (str.chars().allMatch(Character::isWhitespace)) throw new
>>          IllegalArgumentException(message);
>>
>> and 3. Copying StringUtils.isNumeric as DefaultArtifact.isDigits.
>>
>> It would be nice if Java had a directive to do such copies at build-time,
>> removing run-time dependencies while preventing code duplication.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Remove Artifact Commons-Lang Dependency?

Mark James
Karl, I'd like users of my JAR to have to install just this one JAR file (so no
un-archiving required), and not have to ask them to also install the Maven
package to their classpaths.

To do this I'm compiling parts of Maven into my JAR, as allowed by the Apache
Licence, eliminating the commons-lang3 dependencies so I don't have to also
compile that in.

It's great that you're currently working on dependency reduction.

Mark

On 31/12/2019 23:45, Karl Heinz Marbaise wrote:

> hi Mark,
>
> On 31.12.19 12:54, Mark James wrote:
>> Karl, I'd like to embed Maven version string comparison in my JAR so my
>> users don't have to install both Maven and Commons-Lang.
>
>
> Users don't have to install Maven and commons-lang3. They will get it
> with their installation package (Download from maven.apache.org) in the
> lib directory...
>
> I'm currently checking and working on removing dependencies which are
> not really needed[1].
>
> Maybe you can explain more in details what you are trying to do or
> helping (of course appreciated)...
>
> cause at the moment I don't understand which way you are walking?
>
>
> Maybe related to the post we have a misunderstanding ?
>
> Kind regards
> Karl Heinz Marbaise
>
> [1]: https://issues.apache.org/jira/browse/MNG-6829
>
>
>> But I'd like to
>> do this in a way that my JAR isn't an order-of-magnitude bigger.
>>
>> I've found I can embed just
>>
>> org.apache.maven.artifact
>> org.apache.maven.artifact.handler
>> org.apache.maven.artifact.metadata
>> org.apache.maven.artifact.repository
>> org.apache.maven.artifact.repository.layout
>> org.apache.maven.artifact.repository.metadata
>> org.apache.maven.artifact.resolver
>> org.apache.maven.artifact.resolver.filter
>> org.apache.maven.artifact.versioning
>> org.apache.maven.repository
>> org.apache.maven.repository.legacy.metadata
>>
>> as long as I make the small mods I posted to remove the Commons-Lang
>> dependency.
>>
>> Should I keep these mods as a custom fork, or would they be a worthwhile
>> patch to the distribution?
>>
>> Mark
>>
>> On 26/11/2019 05:01, Karl Heinz Marbaise wrote:
>>> Hi Mark,
>>>
>>> can you tell us on which part of Maven you are referencing? Or do you
>>> reference your own project?
>>>
>>> Maven Core ? a particular plugin ?
>>>
>>> Kind regards
>>> Karl Heinz Marbaise
>>>
>>> On 25.11.19 03:08, Mark James wrote:
>>>> Hello,
>>>>
>>>> Is there any chance of removing the dependency of Artifact on
>>>> Commons-Lang?
>>>> Something nine times bigger is pulled in just to reference the String
>>>> utility
>>>> functions isNotEmpty, notBlank, and isNumeric.
>>>>
>>>> I understand the advantages of libraries, but this comes at more of a
>>>> cost in
>>>> Java because common Java libraries are less likely to be on the
>>>> system than
>>>> native libraries, and so must be either specified as a dependency
>>>> (that must be
>>>> downloaded and added to build and class paths), distributed with the
>>>> using JAR
>>>> (requiring an installation expansion), or embedded into using JARs
>>>> (defeating
>>>> the space-saving advantage). Semi-automated dependency resolution
>>>> probably makes
>>>> this easier, but many such as myself aren't familiar with it.
>>>>
>>>> I'd like to be able to distribute my package as a single JAR, with
>>>> Artifact but
>>>> not Commons-Lang embedded. But this currently needs the following
>>>> changes:
>>>>
>>>> 1. Replacing StringUtils.isNotEmpty in DefaultArtifact with a not-null +
>>>> positive-length test.
>>>>
>>>> 2. In ArtifactUtils.notBlank, replacing
>>>>
>>>>          Validate.notBlank( str, message );
>>>>
>>>>      with
>>>>
>>>>          for (int i=0; i < str.length(); i++) if
>>>>          (!Character.isWhitespace(str.charAt(i))) return;
>>>>          throw new IllegalArgumentException(message);
>>>>
>>>>      or, using Java 8 code,
>>>>
>>>>          if (str.chars().allMatch(Character::isWhitespace)) throw new
>>>>          IllegalArgumentException(message);
>>>>
>>>> and 3. Copying StringUtils.isNumeric as DefaultArtifact.isDigits.
>>>>
>>>> It would be nice if Java had a directive to do such copies at
>>>> build-time,
>>>> removing run-time dependencies while preventing code duplication.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Remove Artifact Commons-Lang Dependency?

michaelo
In reply to this post by Mark James
Am 2019-11-25 um 03:08 schrieb Mark James:

> Hello,
>
> Is there any chance of removing the dependency of Artifact on Commons-Lang?
> Something nine times bigger is pulled in just to reference the String utility
> functions isNotEmpty, notBlank, and isNumeric.
>
> I understand the advantages of libraries, but this comes at more of a cost in
> Java because common Java libraries are less likely to be on the system than
> native libraries, and so must be either specified as a dependency (that must be
> downloaded and added to build and class paths), distributed with the using JAR
> (requiring an installation expansion), or embedded into using JARs (defeating
> the space-saving advantage). Semi-automated dependency resolution probably makes
> this easier, but many such as myself aren't familiar with it.
>
> I'd like to be able to distribute my package as a single JAR, with Artifact but
> not Commons-Lang embedded. But this currently needs the following changes:
>
> 1. Replacing StringUtils.isNotEmpty in DefaultArtifact with a not-null +
> positive-length test.
>
> 2. In ArtifactUtils.notBlank, replacing
>
>          Validate.notBlank( str, message );
>
>      with
>
>          for (int i=0; i < str.length(); i++) if
>          (!Character.isWhitespace(str.charAt(i))) return;
>          throw new IllegalArgumentException(message);
>
>      or, using Java 8 code,
>
>          if (str.chars().allMatch(Character::isWhitespace)) throw new
>          IllegalArgumentException(message);

These are not equivalient. Validate#notBlank throws NPE on null input,
those alternatives don't do. I'd has to be interface specification equal.

M

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Remove Artifact Commons-Lang Dependency?

Mark James
In reply to this post by Mark James
On 01/01/2020 00:50, Karl Heinz Marbaise wrote:
> But I don't understand why you are compiling parts of Maven into your JAR ?

Karl, my JAR (which provides an API that its users use in their Java apps) needs
to order version strings. Rather than write that myself, I would like to
efficiently embed Maven's comparison standard/algorithm.

I'm hoping that this standard, which wll be client-side in the service I'm
developing, sufficiently matches Ruby's equivalent, which I'm using server-side:
https://docs.ruby-lang.org/en/2.6.0/Gem/Version.html

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Remove Artifact Commons-Lang Dependency?

Mark James
In reply to this post by michaelo
On 01/01/2020 01:13, Michael Osipov wrote:

> 2. In ArtifactUtils.notBlank, replacing
>>
>>          Validate.notBlank( str, message );
>>
>>      with
>>
>>          for (int i=0; i < str.length(); i++) if
>>          (!Character.isWhitespace(str.charAt(i))) return;
>>          throw new IllegalArgumentException(message);
>>
>>      or, using Java 8 code,
>>
>>          if (str.chars().allMatch(Character::isWhitespace)) throw new
>>          IllegalArgumentException(message);
>
> These are not equivalient. Validate#notBlank throws NPE on null input, those
> alternatives don't do. I'd has to be interface specification equal.
>
> M

Thanks Michael for picking that up.

So should be

if (str != null) for (int i=0; i < str.length(); i++)
    if (!Character.isWhitespace(str.charAt(i))) return;
throw new IllegalArgumentException(message);

  or, using Java 8 code,

if (str == null || str.chars().allMatch(Character::isWhitespace))
    throw new IllegalArgumentException(message);


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Remove Artifact Commons-Lang Dependency?

Mark James
My notBlank code was actually correct. But I hadn't made clear that this code
wasn't replacing the whole notBlank method, but only its inner part, not
changing the quick initial test, which also tests for nulls:

    private static void notBlank( String str, String message )
    {
        int c = str != null && str.length() > 0 ? str.charAt( 0 ) : 0;
        if ( ( c < '0' || c > '9' ) && ( c < 'a' || c > 'z' )  )
        {
            for (int i = 0; i < str.length(); i++) {
                if (!Character.isWhitespace(str.charAt(i))) {
                    return;
                }
            }
            throw new IllegalArgumentException(message);
        }
    }


On 01/01/2020 03:18, Mark James wrote:

> On 01/01/2020 01:13, Michael Osipov wrote:
>> 2. In ArtifactUtils.notBlank, replacing
>>>          Validate.notBlank( str, message );
>>>
>>>      with
>>>
>>>          for (int i=0; i < str.length(); i++) if
>>>          (!Character.isWhitespace(str.charAt(i))) return;
>>>          throw new IllegalArgumentException(message);
>>>
>>>      or, using Java 8 code,
>>>
>>>          if (str.chars().allMatch(Character::isWhitespace)) throw new
>>>          IllegalArgumentException(message);
>> These are not equivalient. Validate#notBlank throws NPE on null input, those
>> alternatives don't do. I'd has to be interface specification equal.
>>
>> M
> Thanks Michael for picking that up.
>
> So should be
>
> if (str != null) for (int i=0; i < str.length(); i++)
>     if (!Character.isWhitespace(str.charAt(i))) return;
> throw new IllegalArgumentException(message);
>
>   or, using Java 8 code,
>
> if (str == null || str.chars().allMatch(Character::isWhitespace))
>     throw new IllegalArgumentException(message);
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Remove Artifact Commons-Lang Dependency?

michaelo
In reply to this post by Mark James
Am 2019-12-31 um 17:18 schrieb Mark James:

> On 01/01/2020 01:13, Michael Osipov wrote:
>> 2. In ArtifactUtils.notBlank, replacing
>>>
>>>           Validate.notBlank( str, message );
>>>
>>>       with
>>>
>>>           for (int i=0; i < str.length(); i++) if
>>>           (!Character.isWhitespace(str.charAt(i))) return;
>>>           throw new IllegalArgumentException(message);
>>>
>>>       or, using Java 8 code,
>>>
>>>           if (str.chars().allMatch(Character::isWhitespace)) throw new
>>>           IllegalArgumentException(message);
>>
>> These are not equivalient. Validate#notBlank throws NPE on null input, those
>> alternatives don't do. I'd has to be interface specification equal.
>>
>> M
>
> Thanks Michael for picking that up.
>
> So should be
>
> if (str != null) for (int i=0; i < str.length(); i++)
>      if (!Character.isWhitespace(str.charAt(i))) return;
> throw new IllegalArgumentException(message);
>
>    or, using Java 8 code,
>
> if (str == null || str.chars().allMatch(Character::isWhitespace))
>      throw new IllegalArgumentException(message);
>
>
Not, that is still wrong. null results in NullPointerException, not IAE.
You need two if statements.


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]