Skip to content

Commit 126edff

Browse files
authored
Merge pull request #514 from bci-oss/513-fix-aas-generation-in-native-image
Fix AAS generation in samm-cli native executable
2 parents 9ddea0b + dced2ef commit 126edff

File tree

23 files changed

+461
-97
lines changed

23 files changed

+461
-97
lines changed

.github/workflows/release-workflow.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ jobs:
111111
tar cfvz samm-cli-${{ github.event.inputs.release_version }}-linux-x86_64.tar.gz samm
112112
popd
113113
mv tools/samm-cli/target/samm-cli-${{ github.event.inputs.release_version }}-linux-x86_64.tar.gz .
114-
mv tools/samm-cli/target/samm-cli-*.jar .
114+
cp tools/samm-cli/target/samm-cli-*.jar .
115115
env:
116116
PGP_KEY_PASSWORD: ${{ secrets.PGP_KEY_PASSWORD }}
117117

core/esmf-aspect-meta-model-version-migrator/src/main/java/org/eclipse/esmf/aspectmodel/versionupdate/MigratorServiceLoader.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private MigratorFactory createMigratorFactory( final Class<?> clazz ) {
5151
}
5252

5353
private void loadMigratorService() {
54-
try ( final ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages(
54+
try ( final ScanResult scanResult = new ClassGraph().enableAllInfo().acceptPackages(
5555
MigratorFactory.class.getPackageName() ).scan() ) {
5656
final ClassInfoList migratorFactoryClasses = scanResult
5757
.getClassesImplementing( MigratorFactory.class.getName() );

core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/jsonschema/AspectModelJsonSchemaGeneratorTest.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ private void assertPayloadIsValid( final JsonNode schema, final Aspect aspect )
140140
@EnumSource( value = TestAspect.class, mode = EnumSource.Mode.EXCLUDE, names = {
141141
"ASPECT_WITH_CONSTRAINED_COLLECTION", // Broken model
142142
"ASPECT_WITH_ENUMERATION_WITHOUT_SCALAR_VARIABLE", //Invalid Aspect Model
143-
"MODEL_WITH_CYCLES", // contains cycles
144-
"MODEL_WITH_BROKEN_CYCLES" // also contains cycles, but all of them should be "breakable", need to be investigated
143+
"MODEL_WITH_BROKEN_CYCLES" // contains cycles, but all of them should be "breakable", need to be investigated
145144
} )
146145
public void testGeneration( final TestAspect testAspect ) {
147146
final Aspect aspect = loadAspect( testAspect, KnownVersion.getLatest() );

core/esmf-aspect-model-serializer/src/test/java/org/eclipse/esmf/aspectmodel/serializer/RdfModelCreatorVisitorTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ public class RdfModelCreatorVisitorTest extends MetaModelVersions {
6060
"ASPECT_WITH_ABSTRACT_PROPERTY",
6161
"ASPECT_WITH_MULTIPLE_ENTITIES_SAME_EXTEND",
6262
"ASPECT_WITH_UMLAUT_DESCRIPTION",
63-
"MODEL_WITH_CYCLES",
6463
"MODEL_WITH_BROKEN_CYCLES",
6564
"MODEL_WITH_BLANK_AND_ADDITIONAL_NODES"
6665
} )

core/esmf-aspect-model-validator/src/test/java/org/eclipse/esmf/aspectmodel/validation/services/AspectModelValidatorTest.java

+3-9
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,14 @@ class AspectModelValidatorTest extends MetaModelVersions {
5656
.collect( Collectors.toMap( Function.identity(), AspectModelValidator::new ) );
5757

5858
@Test
59-
void testValidAspect( ) {
59+
void testValidAspect() {
6060
final Try<VersionedModel> validAspectModel = TestResources.getModel( TestAspect.ASPECT, KnownVersion.getLatest() );
6161
final List<Violation> violations = service.get( KnownVersion.getLatest() ).validateModel( validAspectModel );
6262
assertThat( violations ).isEmpty();
6363
}
6464

6565
@ParameterizedTest
66-
@EnumSource( value = TestAspect.class, mode = EnumSource.Mode.EXCLUDE, names = {
67-
"ASPECT_WITH_FIXED_POINT",
68-
"ASPECT_WITH_FIXED_POINT_CONSTRAINT",
69-
"ASPECT_WITH_LANGUAGE_CONSTRAINT",
70-
"MODEL_WITH_CYCLES",
71-
"MODEL_WITH_BROKEN_CYCLES"// contains cycles
72-
} )
66+
@EnumSource( value = TestAspect.class )
7367
void testValidateTestAspectModel( final TestAspect testAspect ) {
7468
final KnownVersion metaModelVersion = KnownVersion.getLatest();
7569
final Try<VersionedModel> tryModel = TestResources.getModel( testAspect, metaModelVersion );
@@ -222,7 +216,7 @@ void testValidationWithMultipleAspects( final KnownVersion metaModelVersion ) {
222216
@ParameterizedTest
223217
@MethodSource( value = "allVersions" )
224218
void testCycleDetection( final KnownVersion metaModelVersion ) {
225-
final Try<VersionedModel> versionedModel = TestResources.getModel( TestAspect.MODEL_WITH_CYCLES, metaModelVersion );
219+
final Try<VersionedModel> versionedModel = TestResources.getModel( InvalidTestAspect.MODEL_WITH_CYCLES, metaModelVersion );
226220
final List<Violation> report = service.get( metaModelVersion ).validateModel( versionedModel );
227221
assertThat( report ).hasSize( 7 );
228222
assertThat( report ).containsAll( cycles(

core/esmf-test-aspect-models/src/main/java/org/eclipse/esmf/test/InvalidTestAspect.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public enum InvalidTestAspect implements TestModel {
2626
MISSING_ASPECT_DECLARATION,
2727
INVALID_EXAMPLE_VALUE_DATATYPE,
2828
INVALID_PREFERRED_NAME_DATATYPE,
29-
RANGE_CONSTRAINT_WITH_WRONG_TYPE;
29+
RANGE_CONSTRAINT_WITH_WRONG_TYPE,
30+
MODEL_WITH_CYCLES;
3031

3132
@Override
3233
public String getName() {

core/esmf-test-aspect-models/src/main/java/org/eclipse/esmf/test/TestAspect.java

-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ public enum TestAspect implements TestModel {
190190
ENTITY_INSTANCE_TEST4,
191191
ASPECT_WITH_ENUM_ONLY_ONE_SEE,
192192

193-
MODEL_WITH_CYCLES,
194193
MODEL_WITH_BROKEN_CYCLES,
195194

196195
ASPECT_WITH_CONSTRAINED_SET,

core/esmf-test-aspect-models/src/test/resources/logback-include.xml

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<logger name="org.apache.jena" level="OFF"/>
2323
<logger name="org.apache.jena.util" level="OFF"/>
2424
<logger name="org.apache.jena.shared" level="OFF"/>
25+
<logger name="org.apache.jena.shared.LockMRSW" level="OFF"/>
2526

2627
<root level="warn">
2728
<appender-ref ref="console"/>

tools/samm-cli/pom.xml

+20
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@
518518
<arg>java.desktop/sun.awt=ALL-UNNAMED</arg>
519519
<arg>--add-exports</arg>
520520
<arg>java.desktop/sun.font=ALL-UNNAMED</arg>
521+
<arg>--add-exports</arg>
522+
<arg>org.graalvm.sdk/org.graalvm.nativeimage.impl=ALL-UNNAMED</arg>
521523
</compilerArgs>
522524
<forceJavacCompilerUse>true</forceJavacCompilerUse>
523525
</configuration>
@@ -648,10 +650,28 @@
648650
<mainClass>${main-class}</mainClass>
649651
<imageName>${binary-name}</imageName>
650652
<buildArgs>
653+
<arg>-H:Name=${binary-name}</arg>
654+
<arg>-H:EnableURLProtocols=http,https</arg>
655+
<arg>--enable-https</arg>
656+
<arg>--no-fallback</arg>
657+
<arg>--report-unsupported-elements-at-runtime</arg>
658+
<arg>--features=org.eclipse.esmf.nativefeatures.SammCliFeatures</arg>
659+
<arg>--language:js</arg>
660+
<arg>-H:JNIConfigurationFiles=src/main/resources/META-INF/native-image/${project.groupId}/${project.artifactId}/jni-config.json</arg>
661+
<arg>-H:DynamicProxyConfigurationFiles=src/main/resources/META-INF/native-image/${project.groupId}/${project.artifactId}/proxy-config.json</arg>
662+
<arg>-H:ReflectionConfigurationFiles=src/main/resources/META-INF/native-image/${project.groupId}/${project.artifactId}/reflect-config.json</arg>
663+
<arg>-H:ResourceConfigurationFiles=src/main/resources/META-INF/native-image/${project.groupId}/${project.artifactId}/resource-config.json</arg>
664+
<arg>-H:-DeadlockWatchdogExitOnTimeout</arg>
665+
<arg>-H:DeadlockWatchdogInterval=0</arg>
666+
<arg>-H:+AddAllCharsets</arg>
667+
<arg>-H:+ReportExceptionStackTraces</arg>
668+
<arg>-H:+PrintClassInitialization</arg>
651669
<arg>-J-XX:MaxRAMPercentage=90.0</arg>
652670
<arg>-J-XX:GCTimeRatio=19</arg>
653671
<arg>-J--add-exports=java.desktop/sun.awt=ALL-UNNAMED</arg>
654672
<arg>-J--add-exports=java.desktop/sun.font=ALL-UNNAMED</arg>
673+
<arg>-J--add-exports=org.graalvm.sdk/org.graalvm.nativeimage.impl=ALL-UNNAMED</arg>
674+
<arg>-J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.configure=ALL-UNNAMED</arg>
655675
</buildArgs>
656676
<quickBuild>true</quickBuild>
657677
<classpath>

tools/samm-cli/src/main/java/org/eclipse/esmf/LoggingMixin.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515

1616
import static picocli.CommandLine.Spec.Target.MIXEE;
1717

18-
import org.slf4j.LoggerFactory;
19-
2018
import ch.qos.logback.classic.Level;
2119
import ch.qos.logback.classic.Logger;
2220
import ch.qos.logback.classic.LoggerContext;
2321
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
2422
import ch.qos.logback.classic.filter.ThresholdFilter;
2523
import ch.qos.logback.classic.spi.ILoggingEvent;
2624
import ch.qos.logback.core.ConsoleAppender;
25+
import org.apache.jena.shared.LockMRSW;
26+
import org.slf4j.LoggerFactory;
2727
import picocli.CommandLine;
2828

2929
public class LoggingMixin {
@@ -72,6 +72,10 @@ public void configureLoggers() {
7272
root.detachAndStopAllAppenders();
7373
root.setLevel( level );
7474

75+
// In any case disable messages from this particularly spammy and unhelpful logger
76+
final Logger lockMrsw = loggerContext.getLogger( LockMRSW.class );
77+
lockMrsw.setLevel( Level.OFF );
78+
7579
if ( level == Level.OFF ) {
7680
return;
7781
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for additional
5+
* information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
package org.eclipse.esmf.nativefeatures;
15+
16+
import static org.graalvm.nativeimage.hosted.RuntimeClassInitialization.initializeAtBuildTime;
17+
18+
import java.util.List;
19+
20+
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.util.ReflectionHelper;
21+
import org.graalvm.nativeimage.Platform;
22+
import org.graalvm.nativeimage.Platforms;
23+
import org.graalvm.nativeimage.hosted.Feature;
24+
25+
/**
26+
* Registers all classes in the AAS model and default implementation packages for reflection in native image builds.
27+
*/
28+
@Platforms( Platform.HOSTED_ONLY.class )
29+
public class AasReflection extends AbstractSammCliFeature {
30+
@Override
31+
public void beforeAnalysis( final BeforeAnalysisAccess access ) {
32+
initializeAtBuildTime( org.eclipse.esmf.substitution.AdminShellConfig.class );
33+
34+
registerClassesInPackage( ReflectionHelper.MODEL_PACKAGE_NAME );
35+
registerClassesInPackage( ReflectionHelper.DEFAULT_IMPLEMENTATION_PACKAGE_NAME );
36+
}
37+
38+
@Override
39+
public List<Class<? extends Feature>> getRequiredFeatures() {
40+
return List.of( ClassGraphFeature.class );
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for additional
5+
* information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
package org.eclipse.esmf.nativefeatures;
15+
16+
import io.github.classgraph.ClassGraph;
17+
import io.github.classgraph.ScanResult;
18+
import org.graalvm.nativeimage.hosted.Feature;
19+
import org.graalvm.nativeimage.hosted.RuntimeReflection;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
23+
/**
24+
* Base class for native compilation features
25+
*/
26+
public abstract class AbstractSammCliFeature implements Feature {
27+
private static final Logger LOG = LoggerFactory.getLogger( AbstractSammCliFeature.class );
28+
29+
/**
30+
* Registers all classes in the given package for reflection.
31+
*
32+
* @param packageName the package name
33+
*/
34+
protected void registerClassesInPackage( final String packageName ) {
35+
try ( final ScanResult scanResult = new ClassGraph().enableAllInfo().acceptPackages( packageName ).scan() ) {
36+
scanResult.getAllClasses().loadClasses().forEach( this::register );
37+
}
38+
}
39+
40+
/**
41+
* Registers the given class for reflection.
42+
*
43+
* @param cls the class
44+
*/
45+
protected void register( final Class<?> cls ) {
46+
LOG.debug( "Registering {} for reflection", cls );
47+
RuntimeReflection.register( cls );
48+
RuntimeReflection.register( cls.getDeclaredConstructors() );
49+
RuntimeReflection.register( cls.getDeclaredMethods() );
50+
RuntimeReflection.register( cls.getDeclaredFields() );
51+
}
52+
53+
/**
54+
* Returns the class for the given class name.
55+
*
56+
* @param className the class name
57+
* @return the class
58+
*/
59+
protected Class<?> getClass( final String className ) {
60+
try {
61+
return Class.forName( className );
62+
} catch ( final ClassNotFoundException exception ) {
63+
throw new RuntimeException( "Could not access class for reflection registry", exception );
64+
}
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for additional
5+
* information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
package org.eclipse.esmf.nativefeatures;
15+
16+
import static org.graalvm.nativeimage.hosted.RuntimeClassInitialization.initializeAtBuildTime;
17+
18+
/**
19+
* Makes ClassGraph available at build time
20+
*/
21+
public class ClassGraphFeature extends AbstractSammCliFeature {
22+
@Override
23+
public void beforeAnalysis( final BeforeAnalysisAccess access ) {
24+
initializeAtBuildTime( io.github.classgraph.AnnotationInfoList.class );
25+
initializeAtBuildTime( io.github.classgraph.AnnotationParameterValueList.class );
26+
initializeAtBuildTime( io.github.classgraph.ClassGraph.class );
27+
initializeAtBuildTime( io.github.classgraph.ClassInfo.class );
28+
initializeAtBuildTime( getClass( "io.github.classgraph.ClassInfo$2" ) );
29+
initializeAtBuildTime( io.github.classgraph.ClassInfoList.class );
30+
initializeAtBuildTime( io.github.classgraph.FieldInfoList.class );
31+
initializeAtBuildTime( io.github.classgraph.MethodInfoList.class );
32+
initializeAtBuildTime( io.github.classgraph.ModulePathInfo.class );
33+
initializeAtBuildTime( io.github.classgraph.ScanResult.class );
34+
initializeAtBuildTime( nonapi.io.github.classgraph.classloaderhandler.ClassLoaderHandlerRegistry.class );
35+
initializeAtBuildTime( nonapi.io.github.classgraph.classpath.ClasspathOrder.class );
36+
initializeAtBuildTime( nonapi.io.github.classgraph.classpath.SystemJarFinder.class );
37+
initializeAtBuildTime( getClass( "nonapi.io.github.classgraph.classpath.SystemJarFinder$1" ) );
38+
initializeAtBuildTime( nonapi.io.github.classgraph.fastzipfilereader.LogicalZipFile.class );
39+
initializeAtBuildTime( getClass( "nonapi.io.github.classgraph.reflection.StandardReflectionDriver" ) );
40+
initializeAtBuildTime( nonapi.io.github.classgraph.utils.FastPathResolver.class );
41+
initializeAtBuildTime( nonapi.io.github.classgraph.utils.JarUtils.class );
42+
initializeAtBuildTime( nonapi.io.github.classgraph.utils.VersionFinder.class );
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for additional
5+
* information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
package org.eclipse.esmf.nativefeatures;
15+
16+
import static org.graalvm.nativeimage.hosted.RuntimeClassInitialization.initializeAtBuildTime;
17+
18+
/**
19+
* Configuration of eagerly initialized Jena classes
20+
*/
21+
public class JenaFeature extends AbstractSammCliFeature {
22+
@Override
23+
public void beforeAnalysis( final BeforeAnalysisAccess access ) {
24+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.Constants" ) );
25+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl" ) );
26+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl" ) );
27+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl" ) );
28+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLEntityManager" ) );
29+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLEntityManager$EncodingInfo" ) );
30+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLEntityScanner" ) );
31+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl" ) );
32+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLScanner" ) );
33+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.XMLVersionDetector" ) );
34+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDProcessor" ) );
35+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator" ) );
36+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.dtd.XMLNSDTDValidator" ) );
37+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.impl.dv.dtd.DTDDVFactoryImpl" ) );
38+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.util.FeatureState" ) );
39+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.util.PropertyState" ) );
40+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.util.XMLChar" ) );
41+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.util.XMLSymbols" ) );
42+
initializeAtBuildTime( getClass( "com.sun.org.apache.xerces.internal.xni.NamespaceContext" ) );
43+
initializeAtBuildTime( getClass( "com.sun.xml.internal.stream.util.ThreadLocalBufferAllocator" ) );
44+
initializeAtBuildTime( getClass( "javax.xml.parsers.FactoryFinder" ) );
45+
initializeAtBuildTime( getClass( "jdk.xml.internal.JdkXmlUtils" ) );
46+
initializeAtBuildTime( getClass( "jdk.xml.internal.SecuritySupport" ) );
47+
initializeAtBuildTime( org.apache.jena.ext.xerces.impl.dv.xs.AnyURIDV.class );
48+
initializeAtBuildTime( org.apache.jena.ext.xerces.impl.dv.xs.BaseSchemaDVFactory.class );
49+
initializeAtBuildTime( org.apache.jena.ext.xerces.impl.dv.xs.ExtendedSchemaDVFactoryImpl.class );
50+
initializeAtBuildTime( org.apache.jena.ext.xerces.impl.dv.xs.QNameDV.class );
51+
initializeAtBuildTime( org.apache.jena.ext.xerces.impl.dv.xs.SchemaDVFactoryImpl.class );
52+
initializeAtBuildTime( org.apache.jena.ext.xerces.impl.dv.xs.XSSimpleTypeDecl.class );
53+
initializeAtBuildTime( org.apache.jena.ext.xerces.impl.dv.xs.XSSimpleTypeDecl.class );
54+
initializeAtBuildTime( getClass( "org.apache.jena.ext.xerces.impl.xpath.regex.Token$CharToken" ) );
55+
initializeAtBuildTime( getClass( "org.apache.jena.ext.xerces.impl.xpath.regex.Token$ClosureToken" ) );
56+
initializeAtBuildTime( getClass( "org.apache.jena.ext.xerces.impl.xpath.regex.Token$ParenToken" ) );
57+
initializeAtBuildTime( getClass( "org.apache.jena.ext.xerces.impl.xpath.regex.Token$UnionToken" ) );
58+
initializeAtBuildTime( org.apache.jena.ext.xerces.util.XercesXMLChar.class );
59+
}
60+
}

0 commit comments

Comments
 (0)