Skip to content

Commit 75c6091

Browse files
committed
enh: jandex deploy
1 parent 113c5dd commit 75c6091

File tree

33 files changed

+1162
-660
lines changed

33 files changed

+1162
-660
lines changed

appserver/common/annotation-framework/osgi.bundle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737
# only if the new code is made subject to such option by the copyright
3838
# holder.
3939
#
40+
# Portions Copyright [2025] [Payara Foundation and/or its affiliates]
4041

4142
-exportcontents: \
4243
org.glassfish.apf; \
4344
org.glassfish.apf.context; \
4445
org.glassfish.apf.factory; \
46+
org.glassfish.apf.jandex; \
4547
org.glassfish.apf.impl; version=${project.osgi.version}
4648

appserver/common/annotation-framework/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@
106106
<groupId>fish.payara.server.core.common</groupId>
107107
<artifactId>common-util</artifactId>
108108
</dependency>
109+
<dependency>
110+
<groupId>fish.payara.server.core.deployment</groupId>
111+
<artifactId>deployment-common</artifactId>
112+
</dependency>
113+
<dependency>
114+
<groupId>fish.payara.server.core.nucleus</groupId>
115+
<artifactId>kernel</artifactId>
116+
</dependency>
109117
<dependency>
110118
<groupId>fish.payara.server.core.common</groupId>
111119
<artifactId>internal-api</artifactId>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.glassfish.apf.hk2;
2+
3+
import org.glassfish.hk2.classmodel.reflect.util.ResourceLocator;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.net.URL;
7+
import java.util.stream.Stream;
8+
9+
class ClassloaderResourceLocatorAdapter implements ResourceLocator {
10+
private static String[] BLACKLIST = {"java/","com/sun"};
11+
12+
private ClassLoader delegate;
13+
14+
ClassloaderResourceLocatorAdapter(ClassLoader delegate) {
15+
this.delegate = delegate;
16+
}
17+
18+
@Override
19+
public InputStream openResourceStream(String name) throws IOException {
20+
return isAllowed(name) ? delegate.getResourceAsStream(name) : null;
21+
}
22+
23+
@Override
24+
public URL getResource(String name) {
25+
return isAllowed(name) ? delegate.getResource(name) : null;
26+
}
27+
28+
private static boolean isAllowed(String name) {
29+
return Stream.of(BLACKLIST).noneMatch(p -> name.startsWith(p));
30+
}
31+
}
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3+
*
4+
* Copyright (c) [2025] Payara Foundation and/or its affiliates. All rights reserved.
5+
*
6+
* The contents of this file are subject to the terms of either the GNU
7+
* General Public License Version 2 only ("GPL") or the Common Development
8+
* and Distribution License("CDDL") (collectively, the "License"). You
9+
* may not use this file except in compliance with the License. You can
10+
* obtain a copy of the License at
11+
* https://github.com/payara/Payara/blob/main/LICENSE.txt
12+
* See the License for the specific
13+
* language governing permissions and limitations under the License.
14+
*
15+
* When distributing the software, include this License Header Notice in each
16+
* file and include the License file at glassfish/legal/LICENSE.txt.
17+
*
18+
* GPL Classpath Exception:
19+
* The Payara Foundation designates this particular file as subject to the "Classpath"
20+
* exception as provided by the Payara Foundation in the GPL Version 2 section of the License
21+
* file that accompanied this code.
22+
*
23+
* Modifications:
24+
* If applicable, add the following below the License Header, with the fields
25+
* enclosed by brackets [] replaced by your own identifying information:
26+
* "Portions Copyright [year] [name of copyright owner]"
27+
*
28+
* Contributor(s):
29+
* If you wish your version of this file to be governed by only the CDDL or
30+
* only the GPL Version 2, indicate your decision by adding "[Contributor]
31+
* elects to include this software in this distribution under the [CDDL or GPL
32+
* Version 2] license." If you don't indicate a single choice of license, a
33+
* recipient has the option to distribute your version of this file under
34+
* either the CDDL, the GPL Version 2 or to extend the choice of license to
35+
* its licensees as provided above. However, if you add GPL Version 2 code
36+
* and therefore, elected the GPL Version 2 license, then the option applies
37+
* only if the new code is made subject to such option by the copyright
38+
* holder.
39+
*/
40+
package org.glassfish.apf.hk2;
41+
42+
import com.sun.enterprise.deploy.shared.ArchiveFactory;
43+
import com.sun.enterprise.v3.server.CommonClassLoaderServiceImpl;
44+
import com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter;
45+
import fish.payara.nucleus.executorservice.PayaraExecutorService;
46+
import jakarta.inject.Inject;
47+
import org.glassfish.api.deployment.DeploymentContext;
48+
import org.glassfish.api.deployment.archive.ReadableArchive;
49+
import org.glassfish.deployment.common.DeploymentProperties;
50+
import org.glassfish.deployment.common.DeploymentUtils;
51+
import org.glassfish.hk2.classmodel.reflect.Parser;
52+
import org.glassfish.hk2.classmodel.reflect.ParsingContext;
53+
import org.glassfish.hk2.classmodel.reflect.Types;
54+
import org.glassfish.hk2.classmodel.reflect.util.CommonModelRegistry;
55+
import org.glassfish.hk2.classmodel.reflect.util.ParsingConfig;
56+
import org.glassfish.hk2.classmodel.reflect.util.ResourceLocator;
57+
import org.glassfish.internal.deployment.DeploymentTracing;
58+
import org.glassfish.internal.deployment.JandexIndexer;
59+
import org.glassfish.internal.deployment.analysis.DeploymentSpan;
60+
import org.glassfish.internal.deployment.analysis.StructuredDeploymentTracing;
61+
import org.jboss.jandex.Index;
62+
import java.io.File;
63+
import java.io.IOException;
64+
import java.net.URI;
65+
import java.net.URISyntaxException;
66+
import java.util.ArrayList;
67+
import java.util.Collections;
68+
import java.util.List;
69+
import java.util.Set;
70+
import java.util.logging.Logger;
71+
72+
class OldLifecycle {
73+
@Inject
74+
CommonClassLoaderServiceImpl commonClassLoaderService;
75+
76+
@Inject
77+
PayaraExecutorService executorService;
78+
79+
@Inject
80+
JandexIndexer jandexIndexer;
81+
82+
@Inject
83+
ArchiveFactory archiveFactory;
84+
85+
private Types getDeplpymentTypes(DeploymentContext context) throws IOException{
86+
synchronized (context) {
87+
Types types = context.getTransientAppMetaData(Types.class.getName(), Types.class);
88+
if (types != null) {
89+
return types;
90+
}
91+
StructuredDeploymentTracing tracing = StructuredDeploymentTracing.load(context);
92+
Boolean skipScanExternalLibProp = Boolean.valueOf(context.getAppProps().getProperty(DeploymentProperties.SKIP_SCAN_EXTERNAL_LIB));
93+
94+
if (skipScanExternalLibProp) {
95+
Index index = null; // jandexIndexer.getIndexFromArchive(context.getSource());
96+
if (index != null) {
97+
context.addTransientAppMetaData(Index.class.getName(), index);
98+
return null;
99+
}
100+
}
101+
Parser parser = getDeployableParser(context.getSource(), skipScanExternalLibProp, false, tracing,
102+
context.getLogger(), context);
103+
ParsingContext parsingContext = parser.getContext();
104+
context.addTransientAppMetaData(Types.class.getName(), parsingContext.getTypes());
105+
context.addTransientAppMetaData(Parser.class.getName(), parser);
106+
return parsingContext.getTypes();
107+
}
108+
}
109+
110+
111+
private Parser getDeployableParser(ReadableArchive source, boolean skipScanExternalLibProp,
112+
boolean modelUnAnnotatedMembers, StructuredDeploymentTracing tracing,
113+
Logger logger, DeploymentContext deploymentContext) throws IOException {
114+
Parser parser = new Parser(createBuilder(modelUnAnnotatedMembers, logger).build());
115+
try(ReadableArchiveScannerAdapter scannerAdapter = new ReadableArchiveScannerAdapter(parser, source)) {
116+
DeploymentSpan mainScanSpan = tracing.startSpan(DeploymentTracing.AppStage.CLASS_SCANNING, source.getName());
117+
return processParsing(skipScanExternalLibProp, tracing, parser, scannerAdapter, mainScanSpan, deploymentContext);
118+
}
119+
}
120+
121+
private Parser getDeployableParser(ReadableArchive source, boolean skipScanExternalLibProp,
122+
boolean modelUnAnnotatedMembers, StructuredDeploymentTracing tracing, Logger logger)
123+
throws java.io.IOException {
124+
Parser parser = new Parser(createBuilder(modelUnAnnotatedMembers, logger).build());
125+
ReadableArchiveScannerAdapter scannerAdapter = new ReadableArchiveScannerAdapter(parser, source);
126+
DeploymentSpan mainScanSpan = tracing.startSpan(DeploymentTracing.AppStage.CLASS_SCANNING, source.getName());
127+
return processParsing(source, skipScanExternalLibProp, tracing, parser, scannerAdapter, mainScanSpan);
128+
}
129+
130+
private Parser processParsing(ReadableArchive source, boolean skipScanExternalLibProp,
131+
StructuredDeploymentTracing tracing, Parser parser,
132+
ReadableArchiveScannerAdapter scannerAdapter, DeploymentSpan mainScanSpan)
133+
throws IOException {
134+
try {
135+
parser.parse(scannerAdapter, () -> mainScanSpan.close());
136+
for (ReadableArchive externalLibArchive : getExternalLibraries(source, skipScanExternalLibProp)) {
137+
ReadableArchiveScannerAdapter libAdapter = null;
138+
try {
139+
DeploymentSpan span = tracing.startSpan(DeploymentTracing.AppStage.CLASS_SCANNING, externalLibArchive.getName());
140+
libAdapter = new ReadableArchiveScannerAdapter(parser, externalLibArchive);
141+
parser.parse(libAdapter, () -> span.close());
142+
} finally {
143+
if (libAdapter != null) {
144+
libAdapter.close();
145+
}
146+
}
147+
}
148+
parser.awaitTermination();
149+
scannerAdapter.close();
150+
return parser;
151+
} catch (InterruptedException e) {
152+
throw new IOException(e);
153+
}
154+
}
155+
156+
private Parser processParsing(boolean skipScanExternalLibProp,
157+
StructuredDeploymentTracing tracing, Parser parser,
158+
ReadableArchiveScannerAdapter scannerAdapter, DeploymentSpan mainScanSpan,
159+
DeploymentContext deploymentContext)
160+
throws IOException {
161+
try {
162+
parser.parse(scannerAdapter, () -> mainScanSpan.close());
163+
List<ReadableArchive> externalLibraries = getExternalLibraries(skipScanExternalLibProp, deploymentContext);
164+
for (ReadableArchive externalLibArchive : externalLibraries) {
165+
DeploymentSpan span = tracing.startSpan(DeploymentTracing.AppStage.CLASS_SCANNING, externalLibArchive.getName());
166+
try (ReadableArchiveScannerAdapter libAdapter = new ReadableArchiveScannerAdapter(parser, externalLibArchive)) {
167+
parser.parse(libAdapter, () -> span.close());
168+
}
169+
}
170+
parser.awaitTermination();
171+
for(ReadableArchive externalLibArchive: externalLibraries) {
172+
externalLibArchive.close();
173+
}
174+
return parser;
175+
} catch (InterruptedException | java.net.URISyntaxException e) {
176+
throw new IOException(e);
177+
}
178+
}
179+
180+
private ParsingContext.Builder createBuilder(boolean modelUnAnnotatedMembers, Logger logger) {
181+
ResourceLocator locator = determineLocator();
182+
// scan the jar and store the result in the deployment context.
183+
ParsingContext.Builder parsingContextBuilder = new ParsingContext.Builder()
184+
.logger(logger)
185+
.executorService(executorService.getUnderlyingExecutorService())
186+
.config(new ParsingConfig() {
187+
@Override
188+
public Set<String> getAnnotationsOfInterest() {
189+
return Collections.emptySet();
190+
}
191+
192+
@Override
193+
public Set<String> getTypesOfInterest() {
194+
return Collections.emptySet();
195+
}
196+
197+
@Override
198+
public boolean modelUnAnnotatedMembers() {
199+
return modelUnAnnotatedMembers;
200+
}
201+
});
202+
// workaround bug in Builder
203+
parsingContextBuilder.locator(locator);
204+
return parsingContextBuilder;
205+
}
206+
207+
private ResourceLocator determineLocator() {
208+
if (CommonModelRegistry.getInstance().canLoadResources()) {
209+
// common model registry will handle our external class dependencies
210+
return null;
211+
}
212+
return new ClassloaderResourceLocatorAdapter(commonClassLoaderService.getCommonClassLoader());
213+
}
214+
private List<ReadableArchive> getExternalLibraries(ReadableArchive source, Boolean skipScanExternalLibProp) throws IOException {
215+
List<ReadableArchive> externalLibArchives = new ArrayList<>();
216+
217+
if (skipScanExternalLibProp) {
218+
// if we skip scanning external libraries, we should just
219+
// return an empty list here
220+
return Collections.emptyList();
221+
}
222+
223+
List<URI> externalLibs = DeploymentUtils.getExternalLibraries(source);
224+
for (URI externalLib : externalLibs) {
225+
externalLibArchives.add(archiveFactory.openArchive(new File(externalLib.getPath())));
226+
}
227+
228+
return externalLibArchives;
229+
}
230+
231+
private List<ReadableArchive> getExternalLibraries(Boolean skipScanExternalLibProp,
232+
DeploymentContext deploymentContext)
233+
throws IOException, URISyntaxException {
234+
List<ReadableArchive> externalLibArchives = new ArrayList<>();
235+
236+
if (skipScanExternalLibProp) {
237+
// if we skip scanning external libraries, we should just
238+
// return an empty list here
239+
return Collections.emptyList();
240+
}
241+
242+
for(URI externalLib : DeploymentUtils.getExternalLibraries(deploymentContext.getSource())) {
243+
externalLibArchives.add(archiveFactory.openArchive(new File(externalLib.getPath())));
244+
}
245+
246+
for (URI externalLib : deploymentContext.getAppLibs()) {
247+
externalLibArchives.add(archiveFactory.openArchive(new File(externalLib.getPath())));
248+
}
249+
250+
return externalLibArchives;
251+
}
252+
}

0 commit comments

Comments
 (0)