Sharang Gupta created CAMEL-26029:
-------------------------------------

             Summary: Package scanning inside a JAR includes sibling packages 
that share the scanned package name as a prefix
                 Key: CAMEL-26029
                 URL: https://issues.apache.org/jira/browse/CAMEL-26029
             Project: Camel
          Issue Type: Bug
          Components: camel-core
    Affects Versions: 4.23.0
            Reporter: Sharang Gupta


{{DefaultPackageScanClassResolver}} scans classes packaged in a JAR with a 
plain prefix check ({{doLoadImplementationsInJar}}: 
{{entry.startsWith(parent)}} where {{parent}} is e.g. {{com/acme/routes}} 
without a trailing slash). As a result, scanning package {{com.acme.routes}} 
also returns every class from {{com.acme.routesupport}}, {{com.acme.routes2}}, 
... when the application runs from a JAR. Scanning the same packages from a 
directory on the classpath (e.g. {{target/classes}}) only returns 
{{com.acme.routes}} and its sub packages, and the sibling 
{{DefaultPackageScanResourceResolver}} already appends the {{/}} before its 
prefix check, so the JAR branch of the class resolver is the odd one out.

Ordinary way to hit it: {{camel.main.base-package-scan=com.acme.routes}} 
(RoutesConfigurer / BaseMainSupport use 
{{PackageScanClassResolver.findImplementations(RoutesBuilder.class, ...)}}) 
with a {{com.acme.routesupport}} package in the same JAR: its {{RoutesBuilder}} 
/ {{@Configuration}} classes get registered too, but only in the packaged 
application, not when running from the IDE or {{target/classes}}.

Reproduced with camel-support 4.23.0 (and {{main}}): a JAR with 
{{com/acme/routes/RouteA.class}}, {{com/acme/routesupport/HelperB.class}}, 
{{com/acme/routes2/RouteC.class}}:

{code}
new DefaultPackageScanClassResolver().findImplementations(Object.class, 
"com.acme.routes")
JAR on classpath       -> [com.acme.routes.RouteA, com.acme.routes2.RouteC, 
com.acme.routesupport.HelperB]
DIRECTORY on classpath -> [com.acme.routes.RouteA]
{code}

The {{PackageScanClassResolver#findImplementations}} javadoc documents the 
contract as "package names to scan (including subpackages)". The {{startsWith}} 
dates back to the original camel-core implementation and no later change 
(CAMEL-21944, CAMEL-22257 touched the file) looked at it; no existing test has 
a sibling package in its fixture JAR.

Fix: match {{parent + "/"}} (or the whole JAR for the root package) in 
{{doLoadImplementationsInJar}}, mirroring the directory branch and the resource 
resolver, plus a unit test in camel-support that builds a fixture JAR with a 
sibling package, and an upgrade-guide note (4.24) since a packaged application 
that accidentally relied on the sibling match will no longer discover those 
classes. PR to follow.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to