Popular New Releases in Reflection
reflection
1.2.2
avo
v0.4.0
better-enums
Better Enums 0.11.3
protoreflect
v1.12.0
Runtime
2.2.2
Popular Libraries in Reflection
by sebastianbergmann php
5788 NOASSERTION
Allows reflection of object attributes, including inherited and non-public ones
by cglib java
4017 Apache-2.0
cglib - Byte Code Generation Library is high level API to generate and transform Java byte code. It is used by AOP, testing, data access frameworks to generate dynamic proxy objects and intercept field access.
by doctrine php
2984 MIT
The Doctrine Reflection project is a simple library used by the various Doctrine projects which adds some additional functionality on top of the reflection API that comes with PHP. It allows you to get the reflection information about classes, methods and properties statically.
by mmcloughlin go
1937 BSD-3-Clause
Generate x86 Assembly with Go
by rttrorg c++
1806 MIT
C++ Reflection Library
by tiann c++
1802 MIT
A library that lets you use reflection without any restriction above Android P
by zouxiaohang c++
1323
TinySTL is a subset of STL(cut some containers and algorithms) and also a superset of STL(add some other containers and algorithms)
by EsotericSoftware java
1217 BSD-3-Clause
High performance Java reflection
by aantron c++
1130 BSD-2-Clause
C++ compile-time enum to string, iteration, in a single header file
Trending New libraries in Reflection
by Cysharp csharp
756 MIT
Zero Allocation StringBuilder for .NET Core and Unity.
by Ubpa c++
339 MIT
Header-only, tiny (99 lines) and powerful C++20 static reflection library.
by ColinLeung-NiloCat csharp
329 MIT
Reusable RendererFeature of MobileScreenSpacePlanarReflection
by JetBrains-Research kotlin
255 Apache-2.0
A plugin for Kotlin compiler for compile-time reflection
by goccy go
252 MIT
Zero-allocation reflection library for Go
by Kink3d csharp
206 NOASSERTION
Planar reflections for Unity's Universal Render Pipeline.
by Ubpa c++
159 MIT
Ubpa Dynamic Reflection
by jsoysouvanh c++
145 MIT
Cross-platform C++17 Runtime Reflection Library
by mikey96 python
130
Top Authors in Reflection
1
4 Libraries
36
2
3 Libraries
11
3
3 Libraries
11
4
3 Libraries
174
5
3 Libraries
6
6
2 Libraries
247
7
2 Libraries
9
8
2 Libraries
498
9
2 Libraries
6
10
2 Libraries
6
1
4 Libraries
36
2
3 Libraries
11
3
3 Libraries
11
4
3 Libraries
174
5
3 Libraries
6
6
2 Libraries
247
7
2 Libraries
9
8
2 Libraries
498
9
2 Libraries
6
10
2 Libraries
6
Trending Kits in Reflection
No Trending Kits are available at this moment for Reflection
Trending Discussions on Reflection
How to convert lidar format las to data.frame?
nexus-staging-maven-plugin: maven deploy failed: An API incompatibility was encountered while executing
Setting up multi-release JAR unit tests
Video_player Crashes Android Emulator in Flutter
How to detect the length of array property using reflection only if it actually is an array?
How do I replace a switch statement over an enum with runtime-dynamic type-based generic dispatch in C#?
java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
Make a Java class visible from any ClassLoader
R2dbc Repositories always null with Mockito
Filling missing values with mean in pyspark
QUESTION
How to convert lidar format las to data.frame?
Asked 2022-Mar-19 at 17:07Lidar data is simply 3d coordinates, usually in las
file format. Сontent example
1library(rgdal)
2library(raster)
3library(tmap)
4library(tmaptools)
5library(lidR)
6library(RStoolbox)
7las_cat <- readLAScatalog("C:/1/078-638.las")
8summary(las_cat)
9opt_chunk_size(las_cat) <- 500
10plot(las_cat, chunk_pattern = TRUE)
11las_cat
12#> class : LAScatalog (v1.2 format 1)
13#> extent : 637999, 638240.5, 6077999, 6079999 (xmin, xmax, ymin, ymax)
14#> coord. ref. : NA
15#> area : 483081.1 units²
16#> points : 3.68 million points
17#> density : 7.6 points/units²
18#> density : 5.6 pulses/units²
19#> num. files : 1
20
Is there a way to get point coordinates in a typical data.frame
for R?
As an example we can use data from this http://data.wvgis.wvu.edu/elevation/.
Also, is there a way to get the angle of reflection, the number of reflections in the data.frame
from the lidar file?
ANSWER
Answered 2022-Mar-19 at 08:58Please find below one possible solution to get a data.table,data.frame
with all the information. You can use as.data.frame()
to get a pure data.frame
but a data.table
is a data.frame
Reprex
NB: I used a .las
dataset built in the lidR
library as it is more convenient.
- The example dataset from
lidR
1library(rgdal)
2library(raster)
3library(tmap)
4library(tmaptools)
5library(lidR)
6library(RStoolbox)
7las_cat <- readLAScatalog("C:/1/078-638.las")
8summary(las_cat)
9opt_chunk_size(las_cat) <- 500
10plot(las_cat, chunk_pattern = TRUE)
11las_cat
12#> class : LAScatalog (v1.2 format 1)
13#> extent : 637999, 638240.5, 6077999, 6079999 (xmin, xmax, ymin, ymax)
14#> coord. ref. : NA
15#> area : 483081.1 units²
16#> points : 3.68 million points
17#> density : 7.6 points/units²
18#> density : 5.6 pulses/units²
19#> num. files : 1
20library(lidR)
21
22LASfile <- system.file("extdata", "example.laz", package="rlas")
23las <- readLAS(LASfile)
24
25summary(las)
26#> class : LAS (v1.0 format 1)
27#> memory : 21.2 Kb
28#> extent : 339002.9, 339015.1, 5248000, 5248001 (xmin, xmax, ymin, ymax)
29#> coord. ref. : NAD83 / UTM zone 17N
30#> area : 16 m²
31#> points : 30 points
32#> density : 1.88 points/m²
33#> density : 1.62 pulses/m²
34#> File signature: LASF
35#> File source ID: 0
36#> Global encoding:
37#> - GPS Time Type: GPS Week Time
38#> - Synthetic Return Numbers: no
39#> - Well Know Text: CRS is GeoTIFF
40#> - Aggregate Model: false
41#> Project ID - GUID: 00000000-0000-0000-0000-000000000000
42#> Version: 1.0
43#> System identifier: LAStools (c) by rapidlasso GmbH
44#> Generating software: las2las (version 201011)
45#> File creation d/y: 343/2011
46#> header size: 227
47#> Offset to point data: 323
48#> Num. var. length record: 1
49#> Point data format: 1
50#> Point data record length: 28
51#> Num. of point records: 30
52#> Num. of points by return: 26 4 0 0 0
53#> Scale factor X Y Z: 0.001 0.001 0.001
54#> Offset X Y Z: 6e+05 6500000 0
55#> min X Y Z: 339002.9 5248000 973.145
56#> max X Y Z: 339015.1 5248001 978.345
57#> Variable Length Records (VLR):
58#> Variable Length Record 1 of 1
59#> Description: by LAStools of rapidlasso GmbH
60#> Tags:
61#> Key 1024 value 1
62#> Key 3072 value 26917
63#> Key 3076 value 9001
64#> Key 4099 value 9001
65#> Extended Variable Length Records (EVLR): void
66
- Suggested code
1library(rgdal)
2library(raster)
3library(tmap)
4library(tmaptools)
5library(lidR)
6library(RStoolbox)
7las_cat <- readLAScatalog("C:/1/078-638.las")
8summary(las_cat)
9opt_chunk_size(las_cat) <- 500
10plot(las_cat, chunk_pattern = TRUE)
11las_cat
12#> class : LAScatalog (v1.2 format 1)
13#> extent : 637999, 638240.5, 6077999, 6079999 (xmin, xmax, ymin, ymax)
14#> coord. ref. : NA
15#> area : 483081.1 units²
16#> points : 3.68 million points
17#> density : 7.6 points/units²
18#> density : 5.6 pulses/units²
19#> num. files : 1
20library(lidR)
21
22LASfile <- system.file("extdata", "example.laz", package="rlas")
23las <- readLAS(LASfile)
24
25summary(las)
26#> class : LAS (v1.0 format 1)
27#> memory : 21.2 Kb
28#> extent : 339002.9, 339015.1, 5248000, 5248001 (xmin, xmax, ymin, ymax)
29#> coord. ref. : NAD83 / UTM zone 17N
30#> area : 16 m²
31#> points : 30 points
32#> density : 1.88 points/m²
33#> density : 1.62 pulses/m²
34#> File signature: LASF
35#> File source ID: 0
36#> Global encoding:
37#> - GPS Time Type: GPS Week Time
38#> - Synthetic Return Numbers: no
39#> - Well Know Text: CRS is GeoTIFF
40#> - Aggregate Model: false
41#> Project ID - GUID: 00000000-0000-0000-0000-000000000000
42#> Version: 1.0
43#> System identifier: LAStools (c) by rapidlasso GmbH
44#> Generating software: las2las (version 201011)
45#> File creation d/y: 343/2011
46#> header size: 227
47#> Offset to point data: 323
48#> Num. var. length record: 1
49#> Point data format: 1
50#> Point data record length: 28
51#> Num. of point records: 30
52#> Num. of points by return: 26 4 0 0 0
53#> Scale factor X Y Z: 0.001 0.001 0.001
54#> Offset X Y Z: 6e+05 6500000 0
55#> min X Y Z: 339002.9 5248000 973.145
56#> max X Y Z: 339015.1 5248001 978.345
57#> Variable Length Records (VLR):
58#> Variable Length Record 1 of 1
59#> Description: by LAStools of rapidlasso GmbH
60#> Tags:
61#> Key 1024 value 1
62#> Key 3072 value 26917
63#> Key 3076 value 9001
64#> Key 4099 value 9001
65#> Extended Variable Length Records (EVLR): void
66payload(las)
67
- Output
1library(rgdal)
2library(raster)
3library(tmap)
4library(tmaptools)
5library(lidR)
6library(RStoolbox)
7las_cat <- readLAScatalog("C:/1/078-638.las")
8summary(las_cat)
9opt_chunk_size(las_cat) <- 500
10plot(las_cat, chunk_pattern = TRUE)
11las_cat
12#> class : LAScatalog (v1.2 format 1)
13#> extent : 637999, 638240.5, 6077999, 6079999 (xmin, xmax, ymin, ymax)
14#> coord. ref. : NA
15#> area : 483081.1 units²
16#> points : 3.68 million points
17#> density : 7.6 points/units²
18#> density : 5.6 pulses/units²
19#> num. files : 1
20library(lidR)
21
22LASfile <- system.file("extdata", "example.laz", package="rlas")
23las <- readLAS(LASfile)
24
25summary(las)
26#> class : LAS (v1.0 format 1)
27#> memory : 21.2 Kb
28#> extent : 339002.9, 339015.1, 5248000, 5248001 (xmin, xmax, ymin, ymax)
29#> coord. ref. : NAD83 / UTM zone 17N
30#> area : 16 m²
31#> points : 30 points
32#> density : 1.88 points/m²
33#> density : 1.62 pulses/m²
34#> File signature: LASF
35#> File source ID: 0
36#> Global encoding:
37#> - GPS Time Type: GPS Week Time
38#> - Synthetic Return Numbers: no
39#> - Well Know Text: CRS is GeoTIFF
40#> - Aggregate Model: false
41#> Project ID - GUID: 00000000-0000-0000-0000-000000000000
42#> Version: 1.0
43#> System identifier: LAStools (c) by rapidlasso GmbH
44#> Generating software: las2las (version 201011)
45#> File creation d/y: 343/2011
46#> header size: 227
47#> Offset to point data: 323
48#> Num. var. length record: 1
49#> Point data format: 1
50#> Point data record length: 28
51#> Num. of point records: 30
52#> Num. of points by return: 26 4 0 0 0
53#> Scale factor X Y Z: 0.001 0.001 0.001
54#> Offset X Y Z: 6e+05 6500000 0
55#> min X Y Z: 339002.9 5248000 973.145
56#> max X Y Z: 339015.1 5248001 978.345
57#> Variable Length Records (VLR):
58#> Variable Length Record 1 of 1
59#> Description: by LAStools of rapidlasso GmbH
60#> Tags:
61#> Key 1024 value 1
62#> Key 3072 value 26917
63#> Key 3076 value 9001
64#> Key 4099 value 9001
65#> Extended Variable Length Records (EVLR): void
66payload(las)
67#> Z gpstime Intensity ReturnNumber NumberOfReturns ScanDirectionFlag
68#> 1 975.589 269347.3 82 1 1 1
69#> 2 974.778 269347.3 54 1 1 1
70#> 3 974.471 269347.3 27 2 2 1
71#> 4 974.025 269347.3 55 2 2 1
72#> 5 974.298 269347.3 117 1 1 0
73#> 6 974.985 269347.3 81 1 1 0
74#> 7 975.182 269347.3 84 1 1 1
75#> 8 974.434 269347.3 104 1 1 1
76#> 9 974.159 269347.3 91 1 1 1
77#> 10 973.145 269347.3 99 1 1 1
78#> 11 976.739 269347.5 87 1 1 1
79#> 12 976.823 269347.5 83 1 1 1
80#> 13 977.227 269347.5 87 1 1 1
81#> 14 975.873 269347.5 87 1 1 1
82#> 15 975.782 269347.5 107 1 1 1
83#> 16 975.353 269347.5 76 1 1 1
84#> 17 974.704 269347.5 113 1 1 1
85#> 18 977.170 269347.5 64 1 1 0
86#> 19 977.757 269347.5 89 1 1 0
87#> 20 978.212 269347.5 98 1 1 0
88#> 21 978.309 269347.5 50 1 2 0
89#> 22 974.816 269347.5 31 2 2 0
90#> 23 978.345 269347.5 51 1 2 1
91#> 24 974.824 269347.5 32 2 2 1
92#> 25 978.014 269347.5 85 1 1 1
93#> 26 977.781 269347.5 94 1 1 1
94#> 27 976.455 269347.5 78 1 1 1
95#> 28 976.313 269347.7 71 1 1 1
96#> 29 975.735 269347.7 75 1 1 1
97#> 30 975.674 269347.7 106 1 1 1
98#> EdgeOfFlightline Classification Synthetic_flag Keypoint_flag Withheld_flag
99#> 1 1 1 FALSE FALSE FALSE
100#> 2 0 1 FALSE FALSE FALSE
101#> 3 0 1 FALSE FALSE FALSE
102#> 4 0 1 FALSE FALSE FALSE
103#> 5 0 1 FALSE FALSE FALSE
104#> 6 0 1 FALSE FALSE FALSE
105#> 7 1 1 FALSE FALSE FALSE
106#> 8 0 1 FALSE FALSE FALSE
107#> 9 0 1 FALSE FALSE FALSE
108#> 10 0 1 FALSE FALSE FALSE
109#> 11 1 1 FALSE FALSE FALSE
110#> 12 0 1 FALSE FALSE FALSE
111#> 13 0 1 FALSE FALSE FALSE
112#> 14 0 1 FALSE FALSE FALSE
113#> 15 0 1 FALSE FALSE FALSE
114#> 16 0 1 FALSE FALSE FALSE
115#> 17 0 1 FALSE FALSE FALSE
116#> 18 0 1 FALSE FALSE FALSE
117#> 19 0 1 FALSE FALSE FALSE
118#> 20 0 1 FALSE FALSE FALSE
119#> 21 0 1 FALSE FALSE FALSE
120#> 22 0 2 FALSE FALSE FALSE
121#> 23 1 1 FALSE FALSE FALSE
122#> 24 1 2 FALSE FALSE FALSE
123#> 25 0 1 FALSE FALSE FALSE
124#> 26 0 1 FALSE FALSE FALSE
125#> 27 0 1 FALSE FALSE FALSE
126#> 28 1 1 FALSE FALSE FALSE
127#> 29 0 2 FALSE FALSE FALSE
128#> 30 0 1 FALSE FALSE FALSE
129#> ScanAngleRank UserData PointSourceID X Y
130#> 1 -21 32 17 339002.9 5248001
131#> 2 -21 32 17 339003.0 5248000
132#> 3 -21 32 17 339002.9 5248000
133#> 4 -21 32 17 339002.9 5248000
134#> 5 -21 32 17 339003.6 5248000
135#> 6 -21 32 17 339003.5 5248000
136#> 7 -21 32 17 339003.6 5248000
137#> 8 -21 32 17 339003.7 5248000
138#> 9 -21 32 17 339003.6 5248000
139#> 10 -21 32 17 339003.7 5248000
140#> 11 -22 32 17 339009.6 5248001
141#> 12 -22 32 17 339009.5 5248001
142#> 13 -22 32 17 339009.2 5248000
143#> 14 -22 32 17 339009.4 5248001
144#> 15 -22 32 17 339009.3 5248000
145#> 16 -22 32 17 339009.3 5248000
146#> 17 -22 32 17 339009.3 5248000
147#> 18 -22 32 17 339009.5 5248000
148#> 19 -22 32 17 339009.5 5248000
149#> 20 -22 32 17 339009.5 5248000
150#> 21 -22 32 17 339009.6 5248000
151#> 22 -22 32 17 339010.7 5248001
152#> 23 -22 32 17 339009.6 5248000
153#> 24 -22 32 17 339010.6 5248001
154#> 25 -22 32 17 339009.5 5248000
155#> 26 -22 32 17 339009.4 5248000
156#> 27 -22 32 17 339009.7 5248000
157#> 28 -22 32 17 339015.1 5248000
158#> 29 -22 32 17 339015.1 5248000
159#> 30 -22 32 17 339015.0 5248000
160
Created on 2022-03-18 by the reprex package (v2.0.1)
QUESTION
nexus-staging-maven-plugin: maven deploy failed: An API incompatibility was encountered while executing
Asked 2022-Feb-11 at 22:39This worked fine for me be building under Java 8. Now under Java 17.01 I get this when I do mvn deploy.
mvn install works fine. I tried 3.6.3 and 3.8.4 and updated (I think) all my plugins to the newest versions.
Any ideas?
1[ERROR] Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy (injected-nexus-deploy) on project persism: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:de
2ploy failed: An API incompatibility was encountered while executing org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
3
4
5[ERROR] import: Entry[import from realm ClassRealm[maven.api, parent: null]]
6[ERROR]
7[ERROR] -----------------------------------------------------
8[ERROR] : Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not "opens java.util" to unnamed module @149f5761
9[ERROR] -> [Help 1]
10org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy (injected-nexus-deploy) on project persism: Execution injected-nexus-deploy of goal org.sona
11type.plugins:nexus-staging-maven-plugin:1.6.8:deploy failed: An API incompatibility was encountered while executing org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
12
13Caused by: org.apache.maven.plugin.PluginExecutionException: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy failed: An API incompatibility was encountered while executing org.son
14atype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
15
POM:
1[ERROR] Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy (injected-nexus-deploy) on project persism: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:de
2ploy failed: An API incompatibility was encountered while executing org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
3
4
5[ERROR] import: Entry[import from realm ClassRealm[maven.api, parent: null]]
6[ERROR]
7[ERROR] -----------------------------------------------------
8[ERROR] : Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not "opens java.util" to unnamed module @149f5761
9[ERROR] -> [Help 1]
10org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy (injected-nexus-deploy) on project persism: Execution injected-nexus-deploy of goal org.sona
11type.plugins:nexus-staging-maven-plugin:1.6.8:deploy failed: An API incompatibility was encountered while executing org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
12
13Caused by: org.apache.maven.plugin.PluginExecutionException: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy failed: An API incompatibility was encountered while executing org.son
14atype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
15<?xml version="1.0" encoding="UTF-8"?>
16<project xmlns="http://maven.apache.org/POM/4.0.0"
17 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
19 <modelVersion>4.0.0</modelVersion>
20
21 <groupId>io.github.sproket</groupId>
22 <artifactId>persism</artifactId>
23 <version>2.0.0</version>
24 <packaging>jar</packaging>
25
26
27 <build>
28 <sourceDirectory>./src</sourceDirectory>
29 <testSourceDirectory>./test</testSourceDirectory>
30 <testResources>
31 <testResource>
32 <directory>./test</directory>
33 <!-- <includes>-->
34 <!-- <include>*.*</include>-->
35 <!-- </includes>-->
36 </testResource>
37 </testResources>
38 <plugins>
39 <plugin>
40 <groupId>org.apache.maven.plugins</groupId>
41 <artifactId>maven-compiler-plugin</artifactId>
42 <version>3.8.1</version>
43 <!-- MSSQL does not seem to able to connect with 16 -->
44 <configuration>
45 <source>17</source>
46 <target>17</target>
47<!-- <compilerArgs>-->
48<!-- <arg>-parameters</arg>-->
49<!-- </compilerArgs>-->
50 </configuration>
51 </plugin>
52
53 <plugin>
54 <groupId>org.apache.maven.plugins</groupId>
55 <artifactId>maven-jar-plugin</artifactId>
56 <version>3.2.0</version>
57 <configuration>
58 <archive>
59 <manifestEntries>
60 <Automatic-Module-Name>sproket.github.io.persism</Automatic-Module-Name>
61 </manifestEntries>
62 </archive>
63 </configuration>
64 </plugin>
65
66 <plugin>
67 <groupId>org.apache.maven.plugins</groupId>
68 <artifactId>maven-source-plugin</artifactId>
69 <version>3.2.1</version>
70 <executions>
71 <execution>
72 <id>attach-sources</id>
73 <goals>
74 <goal>jar-no-fork</goal>
75 </goals>
76 </execution>
77 </executions>
78 </plugin>
79 <plugin>
80 <groupId>org.apache.maven.plugins</groupId>
81 <artifactId>maven-javadoc-plugin</artifactId>
82 <version>3.2.0</version>
83 <configuration>
84 <excludePackageNames>net.sf.persism.log*;net.sf.persism.logging.*</excludePackageNames>
85 <source>17</source>
86 </configuration>
87 <executions>
88 <execution>
89 <id>attach-javadocs</id>
90 <goals>
91 <goal>jar</goal>
92 </goals>
93 </execution>
94 </executions>
95 </plugin>
96 <plugin>
97 <artifactId>maven-surefire-plugin</artifactId>
98 <version>3.0.0-M5</version>
99 <configuration>
100 <excludedGroups>net.sf.persism.categories.ExternalDB,net.sf.persism.categories.TestContainerDB
101 </excludedGroups>
102 </configuration>
103 </plugin>
104 <plugin>
105 <groupId>org.sonatype.plugins</groupId>
106 <artifactId>nexus-staging-maven-plugin</artifactId>
107 <version>1.6.8</version>
108 <extensions>true</extensions>
109 <configuration>
110 <serverId>ossrh</serverId>
111 <nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
112 <autoReleaseAfterClose>true</autoReleaseAfterClose>
113 </configuration>
114 </plugin>
115
116 </plugins>
117 </build>
118
119 <name>persism</name>
120 <description>A zero ceremony ORM for Java</description>
121 <url>https://github.com/sproket/Persism</url>
122
123 <properties>
124 <java.version>17</java.version>
125 <maven.compiler.release>17</maven.compiler.release>
126 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
127 </properties>
128
129 <licenses>
130 <license>
131 <name>BSD-3-Clause License</name>
132 <url>https://github.com/sproket/Persism/blob/master/license.txt</url>
133 </license>
134 </licenses>
135
136 <developers>
137 <developer>
138 <name>Dan Howard</name>
139 <email>--------------------------</email>
140 <organization>io.github</organization>
141 <organizationUrl>https://sproket.github.io/Persism/</organizationUrl>
142 </developer>
143 </developers>
144
145 <distributionManagement>
146 <snapshotRepository>
147 <id>ossrh</id>
148 <url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
149 </snapshotRepository>
150 <repository>
151 <id>ossrh</id>
152 <url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
153 </repository>
154 </distributionManagement>
155
156 <scm>
157 <connection>scm:git:git://github.com/sproket/Persism.git</connection>
158 <developerConnection>scm:git:ssh://github.com/sproket/Persism.git</developerConnection>
159 <url>https://github.com/sproket/Persism</url>
160 </scm>
161
162 <profiles>
163 <profile>
164 <id>include-test-containers-db</id>
165 <activation>
166 <activeByDefault>false</activeByDefault>
167 </activation>
168 <build>
169 <plugins>
170 <plugin>
171 <artifactId>maven-surefire-plugin</artifactId>
172 <version>3.0.0-M5</version>
173 <configuration>
174 <excludedGroups>net.sf.persism.categories.ExternalDB</excludedGroups>
175 </configuration>
176 </plugin>
177 </plugins>
178 </build>
179 </profile>
180
181 <profile>
182 <id>exclude-test-containers-db</id>
183 <activation>
184 <activeByDefault>false</activeByDefault>
185 </activation>
186 <build>
187 <plugins>
188 <plugin>
189 <artifactId>maven-surefire-plugin</artifactId>
190 <version>3.0.0-M5</version>
191 <configuration>
192 <excludedGroups>net.sf.persism.categories.TestContainerDB</excludedGroups>
193 </configuration>
194 </plugin>
195 </plugins>
196 </build>
197 </profile>
198
199 <profile>
200 <id>release</id>
201 <build>
202 <plugins>
203 <plugin>
204 <groupId>org.apache.maven.plugins</groupId>
205 <artifactId>maven-jar-plugin</artifactId>
206 <version>3.2.0</version>
207 <configuration>
208 <archive>
209 <manifestEntries>
210 <Automatic-Module-Name>sproket.github.io.persism</Automatic-Module-Name>
211 </manifestEntries>
212 </archive>
213 </configuration>
214 </plugin>
215 <plugin>
216 <groupId>org.apache.maven.plugins</groupId>
217 <artifactId>maven-source-plugin</artifactId>
218 <version>3.2.1</version>
219 <executions>
220 <execution>
221 <id>attach-sources</id>
222 <goals>
223 <goal>jar-no-fork</goal>
224 </goals>
225 </execution>
226 </executions>
227 </plugin>
228 <plugin>
229 <groupId>org.apache.maven.plugins</groupId>
230 <artifactId>maven-javadoc-plugin</artifactId>
231 <version>3.2.0</version>
232 <executions>
233 <execution>
234 <id>attach-javadocs</id>
235 <goals>
236 <goal>jar</goal>
237 </goals>
238 <configuration>
239 <release>17</release>
240 </configuration>
241 </execution>
242 </executions>
243 </plugin>
244 <plugin>
245 <groupId>org.apache.maven.plugins</groupId>
246 <artifactId>maven-gpg-plugin</artifactId>
247 <version>3.0.1</version>
248 <executions>
249 <execution>
250 <id>sign-artifacts</id>
251 <phase>verify</phase>
252 <goals>
253 <goal>sign</goal>
254 </goals>
255 </execution>
256 </executions>
257 </plugin>
258 </plugins>
259 </build>
260 </profile>
261 </profiles>
262
263
264 <dependencies>
265 <dependency>
266 <groupId>junit</groupId>
267 <artifactId>junit</artifactId>
268 <version>4.13.2</version>
269 <scope>test</scope>
270 </dependency>
271 <dependency>
272 <groupId>com.carrotsearch</groupId>
273 <artifactId>junit-benchmarks</artifactId>
274 <version>0.7.2</version>
275 <scope>test</scope>
276 </dependency>
277 <dependency>
278 <groupId>org.testcontainers</groupId>
279 <artifactId>testcontainers</artifactId>
280 <version>1.15.2</version>
281 <scope>test</scope>
282 </dependency>
283 <dependency>
284 <groupId>ch.qos.logback</groupId>
285 <artifactId>logback-classic</artifactId>
286 <version>1.2.7</version>
287 <scope>provided</scope>
288 </dependency>
289
290 <dependency>
291 <groupId>log4j</groupId>
292 <artifactId>log4j</artifactId>
293 <version>1.2.17</version>
294 <scope>provided</scope>
295 </dependency>
296
297 <dependency>
298 <groupId>org.apache.logging.log4j</groupId>
299 <artifactId>log4j-api</artifactId>
300 <version>2.14.1</version>
301 <scope>provided</scope>
302 </dependency>
303 <dependency>
304 <groupId>org.apache.logging.log4j</groupId>
305 <artifactId>log4j-core</artifactId>
306 <version>2.14.1</version>
307 <scope>provided</scope>
308 </dependency>
309
310
311 <dependency>
312 <groupId>commons-dbcp</groupId>
313 <artifactId>commons-dbcp</artifactId>
314 <version>1.4</version>
315 <scope>test</scope>
316 </dependency>
317
318 <dependency>
319 <groupId>org.firebirdsql.jdbc</groupId>
320 <artifactId>jaybird</artifactId>
321 <version>4.0.2.java8</version>
322 <scope>test</scope>
323 </dependency>
324
325 <dependency>
326 <groupId>org.firebirdsql</groupId>
327 <artifactId>firebird-testcontainers-java</artifactId>
328 <version>1.1.0</version>
329 <scope>test</scope>
330 </dependency>
331
332 <dependency>
333 <groupId>com.h2database</groupId>
334 <artifactId>h2</artifactId>
335 <version>1.4.200</version>
336 <scope>test</scope>
337 </dependency>
338
339 <dependency>
340 <!-- using older version as 2.5.1 collides with ucanaccess -->
341 <groupId>org.hsqldb</groupId>
342 <artifactId>hsqldb</artifactId>
343 <version>2.5.1</version>
344 <scope>test</scope>
345 <!-- <classifier>debug</classifier>-->
346 </dependency>
347
348 <dependency>
349 <groupId>org.apache.derby</groupId>
350 <artifactId>derby</artifactId>
351 <version>10.8.2.2</version>
352 <scope>test</scope>
353 </dependency>
354
355 <!-- OR -Djdk.tls.client.protocols=TLSv1 -->
356 <dependency>
357 <groupId>com.microsoft.sqlserver</groupId>
358 <artifactId>mssql-jdbc</artifactId>
359 <version>8.4.1.jre8</version>
360 <scope>test</scope>
361 </dependency>
362
363 <dependency>
364 <groupId>org.testcontainers</groupId>
365 <artifactId>mssqlserver</artifactId>
366 <version>1.15.2</version>
367 <scope>test</scope>
368 </dependency>
369
370 <dependency>
371 <groupId>mysql</groupId>
372 <artifactId>mysql-connector-java</artifactId>
373 <version>8.0.23</version>
374 <scope>test</scope>
375 </dependency>
376
377 <dependency>
378 <groupId>org.testcontainers</groupId>
379 <artifactId>mysql</artifactId>
380 <version>1.15.2</version>
381 <scope>test</scope>
382 </dependency>
383
384 <dependency>
385 <groupId>net.sourceforge.jtds</groupId>
386 <artifactId>jtds</artifactId>
387 <version>1.3.1</version>
388 <scope>test</scope>
389 </dependency>
390
391 <dependency>
392 <groupId>com.oracle.database.jdbc</groupId>
393 <artifactId>ojdbc8</artifactId>
394 <version>21.3.0.0</version>
395 <scope>test</scope>
396 </dependency>
397
398 <!-- <dependency>-->
399 <!-- <groupId>com.oracle</groupId>-->
400 <!-- <artifactId>ojdbc6</artifactId>-->
401 <!-- <version>11.2.0.4</version>-->
402 <!-- <scope>test</scope>-->
403 <!-- </dependency>-->
404
405 <dependency>
406 <groupId>org.postgresql</groupId>
407 <artifactId>postgresql</artifactId>
408 <version>9.2-1004-jdbc41</version>
409 <scope>test</scope>
410 </dependency>
411 <dependency>
412 <groupId>org.testcontainers</groupId>
413 <artifactId>postgresql</artifactId>
414 <version>1.15.2</version>
415 <scope>test</scope>
416 </dependency>
417
418 <dependency>
419 <groupId>org.xerial</groupId>
420 <artifactId>sqlite-jdbc</artifactId>
421 <version>3.34.0</version>
422 <scope>test</scope>
423 </dependency>
424
425 <dependency>
426 <groupId>net.sf.ucanaccess</groupId>
427 <artifactId>ucanaccess</artifactId>
428 <version>5.0.1</version>
429 <scope>test</scope>
430 </dependency>
431
432 <dependency>
433 <groupId>com.ibm.informix</groupId>
434 <artifactId>informix-jdbc-complete</artifactId>
435 <version>4.50.4.1</version>
436 <scope>test</scope>
437 </dependency>
438
439 <dependency>
440 <groupId>com.toddfast.typeconverter</groupId>
441 <artifactId>typeconverter</artifactId>
442 <version>1.0</version>
443 <scope>test</scope>
444 </dependency>
445
446 <dependency>
447 <groupId>org.reflections</groupId>
448 <artifactId>reflections</artifactId>
449 <version>0.9.11</version>
450 <scope>test</scope>
451 </dependency>
452
453 <!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
454 <dependency>
455 <groupId>javax.persistence</groupId>
456 <artifactId>javax.persistence-api</artifactId>
457 <version>2.2</version>
458 <scope>test</scope>
459 </dependency>
460
461
462 <!-- https://mvnrepository.com/artifact/org.codehaus.mojo/cobertura-maven-plugin -->
463 <!-- DOES NOT WORK with JAVA 8 + -->
464 <!-- <dependency>-->
465 <!-- <groupId>org.codehaus.mojo</groupId>-->
466 <!-- <artifactId>cobertura-maven-plugin</artifactId>-->
467 <!-- <version>2.7</version>-->
468 <!-- <scope>test</scope>-->
469 <!-- <exclusions>-->
470 <!-- <exclusion>-->
471 <!-- <groupId>com.sun</groupId>-->
472 <!-- <artifactId>tools</artifactId>-->
473 <!-- </exclusion>-->
474 <!-- </exclusions>-->
475 <!-- </dependency>-->
476
477
478 </dependencies>
479
480</project>
481
ANSWER
Answered 2022-Feb-11 at 22:39Update: Version 1.6.9 has been released and should fix this issue! 🎉
This is actually a known bug, which is now open for quite a while: OSSRH-66257. There are two known workarounds:
1. Open ModulesAs a workaround, use --add-opens
to give the library causing the problem access to the required classes:
1[ERROR] Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy (injected-nexus-deploy) on project persism: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:de
2ploy failed: An API incompatibility was encountered while executing org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
3
4
5[ERROR] import: Entry[import from realm ClassRealm[maven.api, parent: null]]
6[ERROR]
7[ERROR] -----------------------------------------------------
8[ERROR] : Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not "opens java.util" to unnamed module @149f5761
9[ERROR] -> [Help 1]
10org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy (injected-nexus-deploy) on project persism: Execution injected-nexus-deploy of goal org.sona
11type.plugins:nexus-staging-maven-plugin:1.6.8:deploy failed: An API incompatibility was encountered while executing org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
12
13Caused by: org.apache.maven.plugin.PluginExecutionException: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy failed: An API incompatibility was encountered while executing org.son
14atype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
15<?xml version="1.0" encoding="UTF-8"?>
16<project xmlns="http://maven.apache.org/POM/4.0.0"
17 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
19 <modelVersion>4.0.0</modelVersion>
20
21 <groupId>io.github.sproket</groupId>
22 <artifactId>persism</artifactId>
23 <version>2.0.0</version>
24 <packaging>jar</packaging>
25
26
27 <build>
28 <sourceDirectory>./src</sourceDirectory>
29 <testSourceDirectory>./test</testSourceDirectory>
30 <testResources>
31 <testResource>
32 <directory>./test</directory>
33 <!-- <includes>-->
34 <!-- <include>*.*</include>-->
35 <!-- </includes>-->
36 </testResource>
37 </testResources>
38 <plugins>
39 <plugin>
40 <groupId>org.apache.maven.plugins</groupId>
41 <artifactId>maven-compiler-plugin</artifactId>
42 <version>3.8.1</version>
43 <!-- MSSQL does not seem to able to connect with 16 -->
44 <configuration>
45 <source>17</source>
46 <target>17</target>
47<!-- <compilerArgs>-->
48<!-- <arg>-parameters</arg>-->
49<!-- </compilerArgs>-->
50 </configuration>
51 </plugin>
52
53 <plugin>
54 <groupId>org.apache.maven.plugins</groupId>
55 <artifactId>maven-jar-plugin</artifactId>
56 <version>3.2.0</version>
57 <configuration>
58 <archive>
59 <manifestEntries>
60 <Automatic-Module-Name>sproket.github.io.persism</Automatic-Module-Name>
61 </manifestEntries>
62 </archive>
63 </configuration>
64 </plugin>
65
66 <plugin>
67 <groupId>org.apache.maven.plugins</groupId>
68 <artifactId>maven-source-plugin</artifactId>
69 <version>3.2.1</version>
70 <executions>
71 <execution>
72 <id>attach-sources</id>
73 <goals>
74 <goal>jar-no-fork</goal>
75 </goals>
76 </execution>
77 </executions>
78 </plugin>
79 <plugin>
80 <groupId>org.apache.maven.plugins</groupId>
81 <artifactId>maven-javadoc-plugin</artifactId>
82 <version>3.2.0</version>
83 <configuration>
84 <excludePackageNames>net.sf.persism.log*;net.sf.persism.logging.*</excludePackageNames>
85 <source>17</source>
86 </configuration>
87 <executions>
88 <execution>
89 <id>attach-javadocs</id>
90 <goals>
91 <goal>jar</goal>
92 </goals>
93 </execution>
94 </executions>
95 </plugin>
96 <plugin>
97 <artifactId>maven-surefire-plugin</artifactId>
98 <version>3.0.0-M5</version>
99 <configuration>
100 <excludedGroups>net.sf.persism.categories.ExternalDB,net.sf.persism.categories.TestContainerDB
101 </excludedGroups>
102 </configuration>
103 </plugin>
104 <plugin>
105 <groupId>org.sonatype.plugins</groupId>
106 <artifactId>nexus-staging-maven-plugin</artifactId>
107 <version>1.6.8</version>
108 <extensions>true</extensions>
109 <configuration>
110 <serverId>ossrh</serverId>
111 <nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
112 <autoReleaseAfterClose>true</autoReleaseAfterClose>
113 </configuration>
114 </plugin>
115
116 </plugins>
117 </build>
118
119 <name>persism</name>
120 <description>A zero ceremony ORM for Java</description>
121 <url>https://github.com/sproket/Persism</url>
122
123 <properties>
124 <java.version>17</java.version>
125 <maven.compiler.release>17</maven.compiler.release>
126 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
127 </properties>
128
129 <licenses>
130 <license>
131 <name>BSD-3-Clause License</name>
132 <url>https://github.com/sproket/Persism/blob/master/license.txt</url>
133 </license>
134 </licenses>
135
136 <developers>
137 <developer>
138 <name>Dan Howard</name>
139 <email>--------------------------</email>
140 <organization>io.github</organization>
141 <organizationUrl>https://sproket.github.io/Persism/</organizationUrl>
142 </developer>
143 </developers>
144
145 <distributionManagement>
146 <snapshotRepository>
147 <id>ossrh</id>
148 <url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
149 </snapshotRepository>
150 <repository>
151 <id>ossrh</id>
152 <url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
153 </repository>
154 </distributionManagement>
155
156 <scm>
157 <connection>scm:git:git://github.com/sproket/Persism.git</connection>
158 <developerConnection>scm:git:ssh://github.com/sproket/Persism.git</developerConnection>
159 <url>https://github.com/sproket/Persism</url>
160 </scm>
161
162 <profiles>
163 <profile>
164 <id>include-test-containers-db</id>
165 <activation>
166 <activeByDefault>false</activeByDefault>
167 </activation>
168 <build>
169 <plugins>
170 <plugin>
171 <artifactId>maven-surefire-plugin</artifactId>
172 <version>3.0.0-M5</version>
173 <configuration>
174 <excludedGroups>net.sf.persism.categories.ExternalDB</excludedGroups>
175 </configuration>
176 </plugin>
177 </plugins>
178 </build>
179 </profile>
180
181 <profile>
182 <id>exclude-test-containers-db</id>
183 <activation>
184 <activeByDefault>false</activeByDefault>
185 </activation>
186 <build>
187 <plugins>
188 <plugin>
189 <artifactId>maven-surefire-plugin</artifactId>
190 <version>3.0.0-M5</version>
191 <configuration>
192 <excludedGroups>net.sf.persism.categories.TestContainerDB</excludedGroups>
193 </configuration>
194 </plugin>
195 </plugins>
196 </build>
197 </profile>
198
199 <profile>
200 <id>release</id>
201 <build>
202 <plugins>
203 <plugin>
204 <groupId>org.apache.maven.plugins</groupId>
205 <artifactId>maven-jar-plugin</artifactId>
206 <version>3.2.0</version>
207 <configuration>
208 <archive>
209 <manifestEntries>
210 <Automatic-Module-Name>sproket.github.io.persism</Automatic-Module-Name>
211 </manifestEntries>
212 </archive>
213 </configuration>
214 </plugin>
215 <plugin>
216 <groupId>org.apache.maven.plugins</groupId>
217 <artifactId>maven-source-plugin</artifactId>
218 <version>3.2.1</version>
219 <executions>
220 <execution>
221 <id>attach-sources</id>
222 <goals>
223 <goal>jar-no-fork</goal>
224 </goals>
225 </execution>
226 </executions>
227 </plugin>
228 <plugin>
229 <groupId>org.apache.maven.plugins</groupId>
230 <artifactId>maven-javadoc-plugin</artifactId>
231 <version>3.2.0</version>
232 <executions>
233 <execution>
234 <id>attach-javadocs</id>
235 <goals>
236 <goal>jar</goal>
237 </goals>
238 <configuration>
239 <release>17</release>
240 </configuration>
241 </execution>
242 </executions>
243 </plugin>
244 <plugin>
245 <groupId>org.apache.maven.plugins</groupId>
246 <artifactId>maven-gpg-plugin</artifactId>
247 <version>3.0.1</version>
248 <executions>
249 <execution>
250 <id>sign-artifacts</id>
251 <phase>verify</phase>
252 <goals>
253 <goal>sign</goal>
254 </goals>
255 </execution>
256 </executions>
257 </plugin>
258 </plugins>
259 </build>
260 </profile>
261 </profiles>
262
263
264 <dependencies>
265 <dependency>
266 <groupId>junit</groupId>
267 <artifactId>junit</artifactId>
268 <version>4.13.2</version>
269 <scope>test</scope>
270 </dependency>
271 <dependency>
272 <groupId>com.carrotsearch</groupId>
273 <artifactId>junit-benchmarks</artifactId>
274 <version>0.7.2</version>
275 <scope>test</scope>
276 </dependency>
277 <dependency>
278 <groupId>org.testcontainers</groupId>
279 <artifactId>testcontainers</artifactId>
280 <version>1.15.2</version>
281 <scope>test</scope>
282 </dependency>
283 <dependency>
284 <groupId>ch.qos.logback</groupId>
285 <artifactId>logback-classic</artifactId>
286 <version>1.2.7</version>
287 <scope>provided</scope>
288 </dependency>
289
290 <dependency>
291 <groupId>log4j</groupId>
292 <artifactId>log4j</artifactId>
293 <version>1.2.17</version>
294 <scope>provided</scope>
295 </dependency>
296
297 <dependency>
298 <groupId>org.apache.logging.log4j</groupId>
299 <artifactId>log4j-api</artifactId>
300 <version>2.14.1</version>
301 <scope>provided</scope>
302 </dependency>
303 <dependency>
304 <groupId>org.apache.logging.log4j</groupId>
305 <artifactId>log4j-core</artifactId>
306 <version>2.14.1</version>
307 <scope>provided</scope>
308 </dependency>
309
310
311 <dependency>
312 <groupId>commons-dbcp</groupId>
313 <artifactId>commons-dbcp</artifactId>
314 <version>1.4</version>
315 <scope>test</scope>
316 </dependency>
317
318 <dependency>
319 <groupId>org.firebirdsql.jdbc</groupId>
320 <artifactId>jaybird</artifactId>
321 <version>4.0.2.java8</version>
322 <scope>test</scope>
323 </dependency>
324
325 <dependency>
326 <groupId>org.firebirdsql</groupId>
327 <artifactId>firebird-testcontainers-java</artifactId>
328 <version>1.1.0</version>
329 <scope>test</scope>
330 </dependency>
331
332 <dependency>
333 <groupId>com.h2database</groupId>
334 <artifactId>h2</artifactId>
335 <version>1.4.200</version>
336 <scope>test</scope>
337 </dependency>
338
339 <dependency>
340 <!-- using older version as 2.5.1 collides with ucanaccess -->
341 <groupId>org.hsqldb</groupId>
342 <artifactId>hsqldb</artifactId>
343 <version>2.5.1</version>
344 <scope>test</scope>
345 <!-- <classifier>debug</classifier>-->
346 </dependency>
347
348 <dependency>
349 <groupId>org.apache.derby</groupId>
350 <artifactId>derby</artifactId>
351 <version>10.8.2.2</version>
352 <scope>test</scope>
353 </dependency>
354
355 <!-- OR -Djdk.tls.client.protocols=TLSv1 -->
356 <dependency>
357 <groupId>com.microsoft.sqlserver</groupId>
358 <artifactId>mssql-jdbc</artifactId>
359 <version>8.4.1.jre8</version>
360 <scope>test</scope>
361 </dependency>
362
363 <dependency>
364 <groupId>org.testcontainers</groupId>
365 <artifactId>mssqlserver</artifactId>
366 <version>1.15.2</version>
367 <scope>test</scope>
368 </dependency>
369
370 <dependency>
371 <groupId>mysql</groupId>
372 <artifactId>mysql-connector-java</artifactId>
373 <version>8.0.23</version>
374 <scope>test</scope>
375 </dependency>
376
377 <dependency>
378 <groupId>org.testcontainers</groupId>
379 <artifactId>mysql</artifactId>
380 <version>1.15.2</version>
381 <scope>test</scope>
382 </dependency>
383
384 <dependency>
385 <groupId>net.sourceforge.jtds</groupId>
386 <artifactId>jtds</artifactId>
387 <version>1.3.1</version>
388 <scope>test</scope>
389 </dependency>
390
391 <dependency>
392 <groupId>com.oracle.database.jdbc</groupId>
393 <artifactId>ojdbc8</artifactId>
394 <version>21.3.0.0</version>
395 <scope>test</scope>
396 </dependency>
397
398 <!-- <dependency>-->
399 <!-- <groupId>com.oracle</groupId>-->
400 <!-- <artifactId>ojdbc6</artifactId>-->
401 <!-- <version>11.2.0.4</version>-->
402 <!-- <scope>test</scope>-->
403 <!-- </dependency>-->
404
405 <dependency>
406 <groupId>org.postgresql</groupId>
407 <artifactId>postgresql</artifactId>
408 <version>9.2-1004-jdbc41</version>
409 <scope>test</scope>
410 </dependency>
411 <dependency>
412 <groupId>org.testcontainers</groupId>
413 <artifactId>postgresql</artifactId>
414 <version>1.15.2</version>
415 <scope>test</scope>
416 </dependency>
417
418 <dependency>
419 <groupId>org.xerial</groupId>
420 <artifactId>sqlite-jdbc</artifactId>
421 <version>3.34.0</version>
422 <scope>test</scope>
423 </dependency>
424
425 <dependency>
426 <groupId>net.sf.ucanaccess</groupId>
427 <artifactId>ucanaccess</artifactId>
428 <version>5.0.1</version>
429 <scope>test</scope>
430 </dependency>
431
432 <dependency>
433 <groupId>com.ibm.informix</groupId>
434 <artifactId>informix-jdbc-complete</artifactId>
435 <version>4.50.4.1</version>
436 <scope>test</scope>
437 </dependency>
438
439 <dependency>
440 <groupId>com.toddfast.typeconverter</groupId>
441 <artifactId>typeconverter</artifactId>
442 <version>1.0</version>
443 <scope>test</scope>
444 </dependency>
445
446 <dependency>
447 <groupId>org.reflections</groupId>
448 <artifactId>reflections</artifactId>
449 <version>0.9.11</version>
450 <scope>test</scope>
451 </dependency>
452
453 <!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
454 <dependency>
455 <groupId>javax.persistence</groupId>
456 <artifactId>javax.persistence-api</artifactId>
457 <version>2.2</version>
458 <scope>test</scope>
459 </dependency>
460
461
462 <!-- https://mvnrepository.com/artifact/org.codehaus.mojo/cobertura-maven-plugin -->
463 <!-- DOES NOT WORK with JAVA 8 + -->
464 <!-- <dependency>-->
465 <!-- <groupId>org.codehaus.mojo</groupId>-->
466 <!-- <artifactId>cobertura-maven-plugin</artifactId>-->
467 <!-- <version>2.7</version>-->
468 <!-- <scope>test</scope>-->
469 <!-- <exclusions>-->
470 <!-- <exclusion>-->
471 <!-- <groupId>com.sun</groupId>-->
472 <!-- <artifactId>tools</artifactId>-->
473 <!-- </exclusion>-->
474 <!-- </exclusions>-->
475 <!-- </dependency>-->
476
477
478 </dependencies>
479
480</project>
481export MAVEN_OPTS="--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED"
482mvn deploy
483
Or you can update the library that causes the problem:
1[ERROR] Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy (injected-nexus-deploy) on project persism: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:de
2ploy failed: An API incompatibility was encountered while executing org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
3
4
5[ERROR] import: Entry[import from realm ClassRealm[maven.api, parent: null]]
6[ERROR]
7[ERROR] -----------------------------------------------------
8[ERROR] : Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not "opens java.util" to unnamed module @149f5761
9[ERROR] -> [Help 1]
10org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy (injected-nexus-deploy) on project persism: Execution injected-nexus-deploy of goal org.sona
11type.plugins:nexus-staging-maven-plugin:1.6.8:deploy failed: An API incompatibility was encountered while executing org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
12
13Caused by: org.apache.maven.plugin.PluginExecutionException: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:deploy failed: An API incompatibility was encountered while executing org.son
14atype.plugins:nexus-staging-maven-plugin:1.6.8:deploy: java.lang.ExceptionInInitializerError: null
15<?xml version="1.0" encoding="UTF-8"?>
16<project xmlns="http://maven.apache.org/POM/4.0.0"
17 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
19 <modelVersion>4.0.0</modelVersion>
20
21 <groupId>io.github.sproket</groupId>
22 <artifactId>persism</artifactId>
23 <version>2.0.0</version>
24 <packaging>jar</packaging>
25
26
27 <build>
28 <sourceDirectory>./src</sourceDirectory>
29 <testSourceDirectory>./test</testSourceDirectory>
30 <testResources>
31 <testResource>
32 <directory>./test</directory>
33 <!-- <includes>-->
34 <!-- <include>*.*</include>-->
35 <!-- </includes>-->
36 </testResource>
37 </testResources>
38 <plugins>
39 <plugin>
40 <groupId>org.apache.maven.plugins</groupId>
41 <artifactId>maven-compiler-plugin</artifactId>
42 <version>3.8.1</version>
43 <!-- MSSQL does not seem to able to connect with 16 -->
44 <configuration>
45 <source>17</source>
46 <target>17</target>
47<!-- <compilerArgs>-->
48<!-- <arg>-parameters</arg>-->
49<!-- </compilerArgs>-->
50 </configuration>
51 </plugin>
52
53 <plugin>
54 <groupId>org.apache.maven.plugins</groupId>
55 <artifactId>maven-jar-plugin</artifactId>
56 <version>3.2.0</version>
57 <configuration>
58 <archive>
59 <manifestEntries>
60 <Automatic-Module-Name>sproket.github.io.persism</Automatic-Module-Name>
61 </manifestEntries>
62 </archive>
63 </configuration>
64 </plugin>
65
66 <plugin>
67 <groupId>org.apache.maven.plugins</groupId>
68 <artifactId>maven-source-plugin</artifactId>
69 <version>3.2.1</version>
70 <executions>
71 <execution>
72 <id>attach-sources</id>
73 <goals>
74 <goal>jar-no-fork</goal>
75 </goals>
76 </execution>
77 </executions>
78 </plugin>
79 <plugin>
80 <groupId>org.apache.maven.plugins</groupId>
81 <artifactId>maven-javadoc-plugin</artifactId>
82 <version>3.2.0</version>
83 <configuration>
84 <excludePackageNames>net.sf.persism.log*;net.sf.persism.logging.*</excludePackageNames>
85 <source>17</source>
86 </configuration>
87 <executions>
88 <execution>
89 <id>attach-javadocs</id>
90 <goals>
91 <goal>jar</goal>
92 </goals>
93 </execution>
94 </executions>
95 </plugin>
96 <plugin>
97 <artifactId>maven-surefire-plugin</artifactId>
98 <version>3.0.0-M5</version>
99 <configuration>
100 <excludedGroups>net.sf.persism.categories.ExternalDB,net.sf.persism.categories.TestContainerDB
101 </excludedGroups>
102 </configuration>
103 </plugin>
104 <plugin>
105 <groupId>org.sonatype.plugins</groupId>
106 <artifactId>nexus-staging-maven-plugin</artifactId>
107 <version>1.6.8</version>
108 <extensions>true</extensions>
109 <configuration>
110 <serverId>ossrh</serverId>
111 <nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
112 <autoReleaseAfterClose>true</autoReleaseAfterClose>
113 </configuration>
114 </plugin>
115
116 </plugins>
117 </build>
118
119 <name>persism</name>
120 <description>A zero ceremony ORM for Java</description>
121 <url>https://github.com/sproket/Persism</url>
122
123 <properties>
124 <java.version>17</java.version>
125 <maven.compiler.release>17</maven.compiler.release>
126 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
127 </properties>
128
129 <licenses>
130 <license>
131 <name>BSD-3-Clause License</name>
132 <url>https://github.com/sproket/Persism/blob/master/license.txt</url>
133 </license>
134 </licenses>
135
136 <developers>
137 <developer>
138 <name>Dan Howard</name>
139 <email>--------------------------</email>
140 <organization>io.github</organization>
141 <organizationUrl>https://sproket.github.io/Persism/</organizationUrl>
142 </developer>
143 </developers>
144
145 <distributionManagement>
146 <snapshotRepository>
147 <id>ossrh</id>
148 <url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
149 </snapshotRepository>
150 <repository>
151 <id>ossrh</id>
152 <url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
153 </repository>
154 </distributionManagement>
155
156 <scm>
157 <connection>scm:git:git://github.com/sproket/Persism.git</connection>
158 <developerConnection>scm:git:ssh://github.com/sproket/Persism.git</developerConnection>
159 <url>https://github.com/sproket/Persism</url>
160 </scm>
161
162 <profiles>
163 <profile>
164 <id>include-test-containers-db</id>
165 <activation>
166 <activeByDefault>false</activeByDefault>
167 </activation>
168 <build>
169 <plugins>
170 <plugin>
171 <artifactId>maven-surefire-plugin</artifactId>
172 <version>3.0.0-M5</version>
173 <configuration>
174 <excludedGroups>net.sf.persism.categories.ExternalDB</excludedGroups>
175 </configuration>
176 </plugin>
177 </plugins>
178 </build>
179 </profile>
180
181 <profile>
182 <id>exclude-test-containers-db</id>
183 <activation>
184 <activeByDefault>false</activeByDefault>
185 </activation>
186 <build>
187 <plugins>
188 <plugin>
189 <artifactId>maven-surefire-plugin</artifactId>
190 <version>3.0.0-M5</version>
191 <configuration>
192 <excludedGroups>net.sf.persism.categories.TestContainerDB</excludedGroups>
193 </configuration>
194 </plugin>
195 </plugins>
196 </build>
197 </profile>
198
199 <profile>
200 <id>release</id>
201 <build>
202 <plugins>
203 <plugin>
204 <groupId>org.apache.maven.plugins</groupId>
205 <artifactId>maven-jar-plugin</artifactId>
206 <version>3.2.0</version>
207 <configuration>
208 <archive>
209 <manifestEntries>
210 <Automatic-Module-Name>sproket.github.io.persism</Automatic-Module-Name>
211 </manifestEntries>
212 </archive>
213 </configuration>
214 </plugin>
215 <plugin>
216 <groupId>org.apache.maven.plugins</groupId>
217 <artifactId>maven-source-plugin</artifactId>
218 <version>3.2.1</version>
219 <executions>
220 <execution>
221 <id>attach-sources</id>
222 <goals>
223 <goal>jar-no-fork</goal>
224 </goals>
225 </execution>
226 </executions>
227 </plugin>
228 <plugin>
229 <groupId>org.apache.maven.plugins</groupId>
230 <artifactId>maven-javadoc-plugin</artifactId>
231 <version>3.2.0</version>
232 <executions>
233 <execution>
234 <id>attach-javadocs</id>
235 <goals>
236 <goal>jar</goal>
237 </goals>
238 <configuration>
239 <release>17</release>
240 </configuration>
241 </execution>
242 </executions>
243 </plugin>
244 <plugin>
245 <groupId>org.apache.maven.plugins</groupId>
246 <artifactId>maven-gpg-plugin</artifactId>
247 <version>3.0.1</version>
248 <executions>
249 <execution>
250 <id>sign-artifacts</id>
251 <phase>verify</phase>
252 <goals>
253 <goal>sign</goal>
254 </goals>
255 </execution>
256 </executions>
257 </plugin>
258 </plugins>
259 </build>
260 </profile>
261 </profiles>
262
263
264 <dependencies>
265 <dependency>
266 <groupId>junit</groupId>
267 <artifactId>junit</artifactId>
268 <version>4.13.2</version>
269 <scope>test</scope>
270 </dependency>
271 <dependency>
272 <groupId>com.carrotsearch</groupId>
273 <artifactId>junit-benchmarks</artifactId>
274 <version>0.7.2</version>
275 <scope>test</scope>
276 </dependency>
277 <dependency>
278 <groupId>org.testcontainers</groupId>
279 <artifactId>testcontainers</artifactId>
280 <version>1.15.2</version>
281 <scope>test</scope>
282 </dependency>
283 <dependency>
284 <groupId>ch.qos.logback</groupId>
285 <artifactId>logback-classic</artifactId>
286 <version>1.2.7</version>
287 <scope>provided</scope>
288 </dependency>
289
290 <dependency>
291 <groupId>log4j</groupId>
292 <artifactId>log4j</artifactId>
293 <version>1.2.17</version>
294 <scope>provided</scope>
295 </dependency>
296
297 <dependency>
298 <groupId>org.apache.logging.log4j</groupId>
299 <artifactId>log4j-api</artifactId>
300 <version>2.14.1</version>
301 <scope>provided</scope>
302 </dependency>
303 <dependency>
304 <groupId>org.apache.logging.log4j</groupId>
305 <artifactId>log4j-core</artifactId>
306 <version>2.14.1</version>
307 <scope>provided</scope>
308 </dependency>
309
310
311 <dependency>
312 <groupId>commons-dbcp</groupId>
313 <artifactId>commons-dbcp</artifactId>
314 <version>1.4</version>
315 <scope>test</scope>
316 </dependency>
317
318 <dependency>
319 <groupId>org.firebirdsql.jdbc</groupId>
320 <artifactId>jaybird</artifactId>
321 <version>4.0.2.java8</version>
322 <scope>test</scope>
323 </dependency>
324
325 <dependency>
326 <groupId>org.firebirdsql</groupId>
327 <artifactId>firebird-testcontainers-java</artifactId>
328 <version>1.1.0</version>
329 <scope>test</scope>
330 </dependency>
331
332 <dependency>
333 <groupId>com.h2database</groupId>
334 <artifactId>h2</artifactId>
335 <version>1.4.200</version>
336 <scope>test</scope>
337 </dependency>
338
339 <dependency>
340 <!-- using older version as 2.5.1 collides with ucanaccess -->
341 <groupId>org.hsqldb</groupId>
342 <artifactId>hsqldb</artifactId>
343 <version>2.5.1</version>
344 <scope>test</scope>
345 <!-- <classifier>debug</classifier>-->
346 </dependency>
347
348 <dependency>
349 <groupId>org.apache.derby</groupId>
350 <artifactId>derby</artifactId>
351 <version>10.8.2.2</version>
352 <scope>test</scope>
353 </dependency>
354
355 <!-- OR -Djdk.tls.client.protocols=TLSv1 -->
356 <dependency>
357 <groupId>com.microsoft.sqlserver</groupId>
358 <artifactId>mssql-jdbc</artifactId>
359 <version>8.4.1.jre8</version>
360 <scope>test</scope>
361 </dependency>
362
363 <dependency>
364 <groupId>org.testcontainers</groupId>
365 <artifactId>mssqlserver</artifactId>
366 <version>1.15.2</version>
367 <scope>test</scope>
368 </dependency>
369
370 <dependency>
371 <groupId>mysql</groupId>
372 <artifactId>mysql-connector-java</artifactId>
373 <version>8.0.23</version>
374 <scope>test</scope>
375 </dependency>
376
377 <dependency>
378 <groupId>org.testcontainers</groupId>
379 <artifactId>mysql</artifactId>
380 <version>1.15.2</version>
381 <scope>test</scope>
382 </dependency>
383
384 <dependency>
385 <groupId>net.sourceforge.jtds</groupId>
386 <artifactId>jtds</artifactId>
387 <version>1.3.1</version>
388 <scope>test</scope>
389 </dependency>
390
391 <dependency>
392 <groupId>com.oracle.database.jdbc</groupId>
393 <artifactId>ojdbc8</artifactId>
394 <version>21.3.0.0</version>
395 <scope>test</scope>
396 </dependency>
397
398 <!-- <dependency>-->
399 <!-- <groupId>com.oracle</groupId>-->
400 <!-- <artifactId>ojdbc6</artifactId>-->
401 <!-- <version>11.2.0.4</version>-->
402 <!-- <scope>test</scope>-->
403 <!-- </dependency>-->
404
405 <dependency>
406 <groupId>org.postgresql</groupId>
407 <artifactId>postgresql</artifactId>
408 <version>9.2-1004-jdbc41</version>
409 <scope>test</scope>
410 </dependency>
411 <dependency>
412 <groupId>org.testcontainers</groupId>
413 <artifactId>postgresql</artifactId>
414 <version>1.15.2</version>
415 <scope>test</scope>
416 </dependency>
417
418 <dependency>
419 <groupId>org.xerial</groupId>
420 <artifactId>sqlite-jdbc</artifactId>
421 <version>3.34.0</version>
422 <scope>test</scope>
423 </dependency>
424
425 <dependency>
426 <groupId>net.sf.ucanaccess</groupId>
427 <artifactId>ucanaccess</artifactId>
428 <version>5.0.1</version>
429 <scope>test</scope>
430 </dependency>
431
432 <dependency>
433 <groupId>com.ibm.informix</groupId>
434 <artifactId>informix-jdbc-complete</artifactId>
435 <version>4.50.4.1</version>
436 <scope>test</scope>
437 </dependency>
438
439 <dependency>
440 <groupId>com.toddfast.typeconverter</groupId>
441 <artifactId>typeconverter</artifactId>
442 <version>1.0</version>
443 <scope>test</scope>
444 </dependency>
445
446 <dependency>
447 <groupId>org.reflections</groupId>
448 <artifactId>reflections</artifactId>
449 <version>0.9.11</version>
450 <scope>test</scope>
451 </dependency>
452
453 <!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
454 <dependency>
455 <groupId>javax.persistence</groupId>
456 <artifactId>javax.persistence-api</artifactId>
457 <version>2.2</version>
458 <scope>test</scope>
459 </dependency>
460
461
462 <!-- https://mvnrepository.com/artifact/org.codehaus.mojo/cobertura-maven-plugin -->
463 <!-- DOES NOT WORK with JAVA 8 + -->
464 <!-- <dependency>-->
465 <!-- <groupId>org.codehaus.mojo</groupId>-->
466 <!-- <artifactId>cobertura-maven-plugin</artifactId>-->
467 <!-- <version>2.7</version>-->
468 <!-- <scope>test</scope>-->
469 <!-- <exclusions>-->
470 <!-- <exclusion>-->
471 <!-- <groupId>com.sun</groupId>-->
472 <!-- <artifactId>tools</artifactId>-->
473 <!-- </exclusion>-->
474 <!-- </exclusions>-->
475 <!-- </dependency>-->
476
477
478 </dependencies>
479
480</project>
481export MAVEN_OPTS="--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED"
482mvn deploy
483<plugin>
484 <groupId>org.sonatype.plugins</groupId>
485 <artifactId>nexus-staging-maven-plugin</artifactId>
486 <version>1.6.8</version>
487 <extensions>true</extensions>
488 <configuration>
489 <serverId>ossrh</serverId>
490 <nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
491 <autoReleaseAfterClose>true</autoReleaseAfterClose>
492 </configuration>
493 <dependencies>
494 <dependency>
495 <groupId>com.thoughtworks.xstream</groupId>
496 <artifactId>xstream</artifactId>
497 <version>1.4.15</version> <!-- apparently this needs to be exactly this version -->
498 </dependency>
499 </dependencies>
500</plugin>
501
QUESTION
Setting up multi-release JAR unit tests
Asked 2022-Jan-26 at 09:21I have a project that uses a lot of reflection, also on "new" Java features such as records and sealed classes. I'm writing a class like this:
1public class RecordHelper {
2 public static boolean isRecord(Class<?> type) {
3 return type.isRecord();
4 }
5}
6
Of course, this only works in Java 16 and higher, so I'm trying to set up a multi-release JAR file, with a default implementation like this:
1public class RecordHelper {
2 public static boolean isRecord(Class<?> type) {
3 return type.isRecord();
4 }
5}
6public class RecordHelper {
7 public static boolean isRecord(Class<?> type) {
8 return false;
9 }
10}
11
I've been able to set that up with Maven using this post on Baeldung, and it works great. It's nice, because it doesn't rely on separate profiles for various versions, which keeps my pom file clean.
But now I need to write tests.
I want to be able to run the test suite on all platforms that I want to support, which means everything from JDK 8 and up. (I don't mind compiling on a different JDK before I run the tests.) Of course, on JDK 16 and up, I also want to test records-related things (and on 17 and up, sealed classes), so that means that I have to compile some records, which means I will inevitably have some class files that won't work on older JDKs.
In my mind, it would make sense to have something like a multi-release JAR file for tests as well, where the records tests get placed in the appropriate place in META-INF/versions
, but of course tests aren't usually packaged in a JAR, so that doesn't work.
Is there a way to get this working in a single-module Maven project without too much repetition?
Of course, it would have to 'accumulate' test classes as the JDK version goes up, e.g. on JDK 8 I only have the 'regular' test classes, on JDK 16 I have the regular ones and the java16
ones, and on JDK 17 I have the regular ones, the java16
ones and the java17
ones. I haven't found a way yet to express this kind of thing in Maven in a concise way, but I'm not a Maven expert.
Or am I looking in the wrong direction, and is it preferable to make a multi-module Maven project, with the main code in one module, and the tests in another, and then generate a multi-module jar for the tests as well? If so, how would I run this jar file on different JDKs?
ANSWER
Answered 2022-Jan-04 at 16:07To test a MRJAR the classes must be packaged as a jar, so don't use surefire with target/classes
, but instead use failsafe during the verify
phase.
And you must run it at least twice, once per targeted Java version.
I would write a unittest, that works for all Java versions, but might skip certain tests.
1public class RecordHelper {
2 public static boolean isRecord(Class<?> type) {
3 return type.isRecord();
4 }
5}
6public class RecordHelper {
7 public static boolean isRecord(Class<?> type) {
8 return false;
9 }
10}
11import static org.junit.jupiter.api.Assertions.assertFalse;
12import static org.junit.jupiter.api.Assertions.assertTrue;
13import static org.junit.jupiter.api.Assumptions.assumeTrue;
14
15import org.junit.jupiter.api.Test;
16
17class RecordHelperTest
18{
19
20 @Test
21 void isNotARecord()
22 {
23 assertFalse( RecordHelper.isRecord(Object.class));
24 }
25
26 @Test
27 void isARecord() throws Exception
28 {
29 assumeTrue( Integer.parseInt( System.getProperty( "java.specification.version" ) ) >= 16 );
30
31 Class c = Class.forName( "jdk.net.UnixDomainPrincipal" );
32 assertTrue( RecordHelper.isRecord(c));
33 }
34
35}
36
How to run it twice, that's up to you, e.g. configure the failsafe plugin twice with different a Toolchain, or rely on a CI server, that builds the project with both JDKs.
https://maven.apache.org/plugins/maven-compiler-plugin/multirelease.html describes several options with their pros and cons as there is no one-fits-all solution.
QUESTION
Video_player Crashes Android Emulator in Flutter
Asked 2022-Jan-11 at 08:53I am trying to use the video_player, but I am getting the below error. I have also added an MRE (minimum reproducible example).
I have used an emulated Pixel 4, an emulated Pixel 4 XL, and an emulator Pixel 5 with the Android Studio Beta, but none of them worked.
The below error was when I was using a Pixel 4 XL, but the error was the same with all of them.
Error:
1~\OneDrive\Documents\Coding\Flutter\video_player_not_working> flutter run
2Using hardware rendering with device sdk gphone x86 64 arm64. If you notice graphics artifacts, consider enabling software
3rendering with "--enable-software-rendering".
4Launching lib\main.dart on sdk gphone x86 64 arm64 in debug mode...
5Checking the license for package Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\licenses
6License for package Android SDK Platform 31 accepted.
7Preparing "Install Android SDK Platform 31 (revision: 1)".
8"Install Android SDK Platform 31 (revision: 1)" ready.
9Installing Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\platforms\android-31
10"Install Android SDK Platform 31 (revision: 1)" complete.
11"Install Android SDK Platform 31 (revision: 1)" finished.
12Running Gradle task 'assembleDebug'... 153.4s
13√ Built build\app\outputs\flutter-apk\app-debug.apk.
14Installing build\app\outputs\flutter-apk\app.apk... 2,093ms
15Syncing files to device sdk gphone x86 64 arm64... 292ms
16
17Flutter run key commands.
18r Hot reload.
19R Hot restart.
20h List all available interactive commands.
21d Detach (terminate "flutter run" but leave application running).
22c Clear the screen
23q Quit (terminate the application on the device).
24
25 Running with sound null safety
26
27An Observatory debugger and profiler on sdk gphone x86 64 arm64 is available at: http://127.0.0.1:51217/xDqrRJJJEMY=/
28W/yer_not_workin( 5318): Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (greylist, reflection, allowed)
29I/ExoPlayerImpl( 5318): Init d52da73 [ExoPlayerLib/2.14.1] [generic_x86_64_arm64, sdk_gphone_x86_64_arm64, Google, 30]
30I/Choreographer( 5318): Skipped 47 frames! The application may be doing too much work on its main thread.
31I/TetheringManager( 5318): registerTetheringEventCallback:com.example.video_player_not_working
32I/VideoCapabilities( 5318): Unsupported profile 4 for video/mp4v-es
33I/OMXClient( 5318): IOmx service obtained
34The Flutter DevTools debugger and profiler on sdk gphone x86 64 arm64 is available at:
35http://127.0.0.1:9102?uri=http://127.0.0.1:51217/xDqrRJJJEMY=/
36D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface
37I/MediaCodec( 5318): [OMX.android.goldfish.h264.decoder] setting surface generation to 5445633
38D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
39D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
40E/ACodec ( 5318): [OMX.android.goldfish.h264.decoder] setPortMode on output to DynamicANWBuffer failed w/ err -1010
41I/ACodec ( 5318): codec does not support config priority (err -1010)
42D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
43D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
44D/SurfaceUtils( 5318): set up nativeWindow 0x70fcbf3cba60 for 1280x720, color 0x13, rotation 0, usage 0x1002900
45W/Gralloc4( 5318): allocator 3.x is not supported
46D/CCodec ( 5318): allocate(c2.android.aac.decoder)
47Lost connection to device.
48
main.dart
:
1~\OneDrive\Documents\Coding\Flutter\video_player_not_working> flutter run
2Using hardware rendering with device sdk gphone x86 64 arm64. If you notice graphics artifacts, consider enabling software
3rendering with "--enable-software-rendering".
4Launching lib\main.dart on sdk gphone x86 64 arm64 in debug mode...
5Checking the license for package Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\licenses
6License for package Android SDK Platform 31 accepted.
7Preparing "Install Android SDK Platform 31 (revision: 1)".
8"Install Android SDK Platform 31 (revision: 1)" ready.
9Installing Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\platforms\android-31
10"Install Android SDK Platform 31 (revision: 1)" complete.
11"Install Android SDK Platform 31 (revision: 1)" finished.
12Running Gradle task 'assembleDebug'... 153.4s
13√ Built build\app\outputs\flutter-apk\app-debug.apk.
14Installing build\app\outputs\flutter-apk\app.apk... 2,093ms
15Syncing files to device sdk gphone x86 64 arm64... 292ms
16
17Flutter run key commands.
18r Hot reload.
19R Hot restart.
20h List all available interactive commands.
21d Detach (terminate "flutter run" but leave application running).
22c Clear the screen
23q Quit (terminate the application on the device).
24
25 Running with sound null safety
26
27An Observatory debugger and profiler on sdk gphone x86 64 arm64 is available at: http://127.0.0.1:51217/xDqrRJJJEMY=/
28W/yer_not_workin( 5318): Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (greylist, reflection, allowed)
29I/ExoPlayerImpl( 5318): Init d52da73 [ExoPlayerLib/2.14.1] [generic_x86_64_arm64, sdk_gphone_x86_64_arm64, Google, 30]
30I/Choreographer( 5318): Skipped 47 frames! The application may be doing too much work on its main thread.
31I/TetheringManager( 5318): registerTetheringEventCallback:com.example.video_player_not_working
32I/VideoCapabilities( 5318): Unsupported profile 4 for video/mp4v-es
33I/OMXClient( 5318): IOmx service obtained
34The Flutter DevTools debugger and profiler on sdk gphone x86 64 arm64 is available at:
35http://127.0.0.1:9102?uri=http://127.0.0.1:51217/xDqrRJJJEMY=/
36D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface
37I/MediaCodec( 5318): [OMX.android.goldfish.h264.decoder] setting surface generation to 5445633
38D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
39D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
40E/ACodec ( 5318): [OMX.android.goldfish.h264.decoder] setPortMode on output to DynamicANWBuffer failed w/ err -1010
41I/ACodec ( 5318): codec does not support config priority (err -1010)
42D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
43D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
44D/SurfaceUtils( 5318): set up nativeWindow 0x70fcbf3cba60 for 1280x720, color 0x13, rotation 0, usage 0x1002900
45W/Gralloc4( 5318): allocator 3.x is not supported
46D/CCodec ( 5318): allocate(c2.android.aac.decoder)
47Lost connection to device.
48import 'dart:async';
49
50import 'package:flutter/material.dart';
51import 'package:video_player/video_player.dart';
52
53void main() => runApp(const VideoPlayerApp());
54
55class VideoPlayerApp extends StatelessWidget {
56 const VideoPlayerApp({Key? key}) : super(key: key);
57
58 @override
59 Widget build(BuildContext context) {
60 return const MaterialApp(
61 title: 'Video Player Demo',
62 home: VideoPlayerScreen(),
63 );
64 }
65}
66
67class VideoPlayerScreen extends StatefulWidget {
68 const VideoPlayerScreen({Key? key}) : super(key: key);
69
70 @override
71 _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
72}
73
74class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
75 late VideoPlayerController _controller;
76 late Future<void> _initializeVideoPlayerFuture;
77
78 @override
79 void initState() {
80 // Create and store the VideoPlayerController. The VideoPlayerController
81 // offers several different constructors to play videos from assets, files,
82 // or the internet.
83 _controller = VideoPlayerController.network(
84 'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
85 );
86
87 // Initialize the controller and store the Future for later use.
88 _initializeVideoPlayerFuture = _controller.initialize();
89
90 // Use the controller to loop the video.
91 _controller.setLooping(true);
92
93 super.initState();
94 }
95
96 @override
97 void dispose() {
98 // Ensure disposing of the VideoPlayerController to free up resources.
99 _controller.dispose();
100
101 super.dispose();
102 }
103
104 @override
105 Widget build(BuildContext context) {
106 return Scaffold(
107 appBar: AppBar(
108 title: const Text('Butterfly Video'),
109 ),
110 // Use a FutureBuilder to display a loading spinner while waiting for the
111 // VideoPlayerController to finish initializing.
112 body: FutureBuilder(
113 future: _initializeVideoPlayerFuture,
114 builder: (context, snapshot) {
115 if (snapshot.connectionState == ConnectionState.done) {
116 // If the VideoPlayerController has finished initialization, use
117 // the data it provides to limit the aspect ratio of the video.
118 return AspectRatio(
119 aspectRatio: _controller.value.aspectRatio,
120 // Use the VideoPlayer widget to display the video.
121 child: VideoPlayer(_controller),
122 );
123 } else {
124 // If the VideoPlayerController is still initializing, show a
125 // loading spinner.
126 return const Center(
127 child: CircularProgressIndicator(),
128 );
129 }
130 },
131 ),
132 floatingActionButton: FloatingActionButton(
133 onPressed: () {
134 // Wrap the play or pause in a call to `setState`. This ensures the
135 // correct icon is shown.
136 setState(() {
137 // If the video is playing, pause it.
138 if (_controller.value.isPlaying) {
139 _controller.pause();
140 } else {
141 // If the video is paused, play it.
142 _controller.play();
143 }
144 });
145 },
146 // Display the correct icon depending on the state of the player.
147 child: Icon(
148 _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
149 ),
150 ),
151 );
152 }
153}
154
pubspec.yaml
1~\OneDrive\Documents\Coding\Flutter\video_player_not_working> flutter run
2Using hardware rendering with device sdk gphone x86 64 arm64. If you notice graphics artifacts, consider enabling software
3rendering with "--enable-software-rendering".
4Launching lib\main.dart on sdk gphone x86 64 arm64 in debug mode...
5Checking the license for package Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\licenses
6License for package Android SDK Platform 31 accepted.
7Preparing "Install Android SDK Platform 31 (revision: 1)".
8"Install Android SDK Platform 31 (revision: 1)" ready.
9Installing Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\platforms\android-31
10"Install Android SDK Platform 31 (revision: 1)" complete.
11"Install Android SDK Platform 31 (revision: 1)" finished.
12Running Gradle task 'assembleDebug'... 153.4s
13√ Built build\app\outputs\flutter-apk\app-debug.apk.
14Installing build\app\outputs\flutter-apk\app.apk... 2,093ms
15Syncing files to device sdk gphone x86 64 arm64... 292ms
16
17Flutter run key commands.
18r Hot reload.
19R Hot restart.
20h List all available interactive commands.
21d Detach (terminate "flutter run" but leave application running).
22c Clear the screen
23q Quit (terminate the application on the device).
24
25 Running with sound null safety
26
27An Observatory debugger and profiler on sdk gphone x86 64 arm64 is available at: http://127.0.0.1:51217/xDqrRJJJEMY=/
28W/yer_not_workin( 5318): Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (greylist, reflection, allowed)
29I/ExoPlayerImpl( 5318): Init d52da73 [ExoPlayerLib/2.14.1] [generic_x86_64_arm64, sdk_gphone_x86_64_arm64, Google, 30]
30I/Choreographer( 5318): Skipped 47 frames! The application may be doing too much work on its main thread.
31I/TetheringManager( 5318): registerTetheringEventCallback:com.example.video_player_not_working
32I/VideoCapabilities( 5318): Unsupported profile 4 for video/mp4v-es
33I/OMXClient( 5318): IOmx service obtained
34The Flutter DevTools debugger and profiler on sdk gphone x86 64 arm64 is available at:
35http://127.0.0.1:9102?uri=http://127.0.0.1:51217/xDqrRJJJEMY=/
36D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface
37I/MediaCodec( 5318): [OMX.android.goldfish.h264.decoder] setting surface generation to 5445633
38D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
39D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
40E/ACodec ( 5318): [OMX.android.goldfish.h264.decoder] setPortMode on output to DynamicANWBuffer failed w/ err -1010
41I/ACodec ( 5318): codec does not support config priority (err -1010)
42D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
43D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
44D/SurfaceUtils( 5318): set up nativeWindow 0x70fcbf3cba60 for 1280x720, color 0x13, rotation 0, usage 0x1002900
45W/Gralloc4( 5318): allocator 3.x is not supported
46D/CCodec ( 5318): allocate(c2.android.aac.decoder)
47Lost connection to device.
48import 'dart:async';
49
50import 'package:flutter/material.dart';
51import 'package:video_player/video_player.dart';
52
53void main() => runApp(const VideoPlayerApp());
54
55class VideoPlayerApp extends StatelessWidget {
56 const VideoPlayerApp({Key? key}) : super(key: key);
57
58 @override
59 Widget build(BuildContext context) {
60 return const MaterialApp(
61 title: 'Video Player Demo',
62 home: VideoPlayerScreen(),
63 );
64 }
65}
66
67class VideoPlayerScreen extends StatefulWidget {
68 const VideoPlayerScreen({Key? key}) : super(key: key);
69
70 @override
71 _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
72}
73
74class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
75 late VideoPlayerController _controller;
76 late Future<void> _initializeVideoPlayerFuture;
77
78 @override
79 void initState() {
80 // Create and store the VideoPlayerController. The VideoPlayerController
81 // offers several different constructors to play videos from assets, files,
82 // or the internet.
83 _controller = VideoPlayerController.network(
84 'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
85 );
86
87 // Initialize the controller and store the Future for later use.
88 _initializeVideoPlayerFuture = _controller.initialize();
89
90 // Use the controller to loop the video.
91 _controller.setLooping(true);
92
93 super.initState();
94 }
95
96 @override
97 void dispose() {
98 // Ensure disposing of the VideoPlayerController to free up resources.
99 _controller.dispose();
100
101 super.dispose();
102 }
103
104 @override
105 Widget build(BuildContext context) {
106 return Scaffold(
107 appBar: AppBar(
108 title: const Text('Butterfly Video'),
109 ),
110 // Use a FutureBuilder to display a loading spinner while waiting for the
111 // VideoPlayerController to finish initializing.
112 body: FutureBuilder(
113 future: _initializeVideoPlayerFuture,
114 builder: (context, snapshot) {
115 if (snapshot.connectionState == ConnectionState.done) {
116 // If the VideoPlayerController has finished initialization, use
117 // the data it provides to limit the aspect ratio of the video.
118 return AspectRatio(
119 aspectRatio: _controller.value.aspectRatio,
120 // Use the VideoPlayer widget to display the video.
121 child: VideoPlayer(_controller),
122 );
123 } else {
124 // If the VideoPlayerController is still initializing, show a
125 // loading spinner.
126 return const Center(
127 child: CircularProgressIndicator(),
128 );
129 }
130 },
131 ),
132 floatingActionButton: FloatingActionButton(
133 onPressed: () {
134 // Wrap the play or pause in a call to `setState`. This ensures the
135 // correct icon is shown.
136 setState(() {
137 // If the video is playing, pause it.
138 if (_controller.value.isPlaying) {
139 _controller.pause();
140 } else {
141 // If the video is paused, play it.
142 _controller.play();
143 }
144 });
145 },
146 // Display the correct icon depending on the state of the player.
147 child: Icon(
148 _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
149 ),
150 ),
151 );
152 }
153}
154name: video_player_not_working
155description: A new Flutter project.
156
157# The following line prevents the package from being accidentally published to
158# pub.dev using `flutter pub publish`. This is preferred for private packages.
159publish_to: 'none' # Remove this line if you wish to publish to pub.dev
160
161# The following defines the version and build number for your application.
162# A version number is three numbers separated by dots, like 1.2.43
163# followed by an optional build number separated by a +.
164# Both the version and the builder number may be overridden in flutter
165# build by specifying --build-name and --build-number, respectively.
166# In Android, build-name is used as versionName while build-number used as versionCode.
167# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
168# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
169# Read more about iOS versioning at
170# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
171version: 1.0.0+1
172
173environment:
174 sdk: ">=2.15.1 <3.0.0"
175
176# Dependencies specify other packages that your package needs in order to work.
177# To automatically upgrade your package dependencies to the latest versions
178# consider running `flutter pub upgrade --major-versions`. Alternatively,
179# dependencies can be manually updated by changing the version numbers below to
180# the latest version available on pub.dev. To see which dependencies have newer
181# versions available, run `flutter pub outdated`.
182dependencies:
183 flutter:
184 sdk: flutter
185
186
187 # The following adds the Cupertino Icons font to your application.
188 # Use with the CupertinoIcons class for iOS style icons.
189 cupertino_icons: ^1.0.2
190 video_player: ^2.2.10
191
192dev_dependencies:
193 flutter_test:
194 sdk: flutter
195
196 # The "flutter_lints" package below contains a set of recommended lints to
197 # encourage good coding practices. The lint set provided by the package is
198 # activated in the `analysis_options.yaml` file located at the root of your
199 # package. See that file for information about deactivating specific lint
200 # rules and activating additional ones.
201 flutter_lints: ^1.0.0
202
203# For information on the generic Dart part of this file, see the
204# following page: https://dart.dev/tools/pub/pubspec
205
206# The following section is specific to Flutter.
207flutter:
208
209 # The following line ensures that the Material Icons font is
210 # included with your application, so that you can use the icons in
211 # the material Icons class.
212 uses-material-design: true
213
214 # To add assets to your application, add an assets section, like this:
215 # assets:
216 # - images/a_dot_burr.jpeg
217 # - images/a_dot_ham.jpeg
218
219 # An image asset can refer to one or more resolution-specific "variants", see
220 # https://flutter.dev/assets-and-images/#resolution-aware.
221
222 # For details regarding adding assets from package dependencies, see
223 # https://flutter.dev/assets-and-images/#from-packages
224
225 # To add custom fonts to your application, add a fonts section here,
226 # in this "flutter" section. Each entry in this list should have a
227 # "family" key with the font family name, and a "fonts" key with a
228 # list giving the asset and other descriptors for the font. For
229 # example:
230 # fonts:
231 # - family: Schyler
232 # fonts:
233 # - asset: fonts/Schyler-Regular.ttf
234 # - asset: fonts/Schyler-Italic.ttf
235 # style: italic
236 # - family: Trajan Pro
237 # fonts:
238 # - asset: fonts/TrajanPro.ttf
239 # - asset: fonts/TrajanPro_Bold.ttf
240 # weight: 700
241 #
242 # For details regarding fonts from package dependencies,
243 # see https://flutter.dev/custom-fonts/#from-packages
244
AndroidManifest.xml
1~\OneDrive\Documents\Coding\Flutter\video_player_not_working> flutter run
2Using hardware rendering with device sdk gphone x86 64 arm64. If you notice graphics artifacts, consider enabling software
3rendering with "--enable-software-rendering".
4Launching lib\main.dart on sdk gphone x86 64 arm64 in debug mode...
5Checking the license for package Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\licenses
6License for package Android SDK Platform 31 accepted.
7Preparing "Install Android SDK Platform 31 (revision: 1)".
8"Install Android SDK Platform 31 (revision: 1)" ready.
9Installing Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\platforms\android-31
10"Install Android SDK Platform 31 (revision: 1)" complete.
11"Install Android SDK Platform 31 (revision: 1)" finished.
12Running Gradle task 'assembleDebug'... 153.4s
13√ Built build\app\outputs\flutter-apk\app-debug.apk.
14Installing build\app\outputs\flutter-apk\app.apk... 2,093ms
15Syncing files to device sdk gphone x86 64 arm64... 292ms
16
17Flutter run key commands.
18r Hot reload.
19R Hot restart.
20h List all available interactive commands.
21d Detach (terminate "flutter run" but leave application running).
22c Clear the screen
23q Quit (terminate the application on the device).
24
25 Running with sound null safety
26
27An Observatory debugger and profiler on sdk gphone x86 64 arm64 is available at: http://127.0.0.1:51217/xDqrRJJJEMY=/
28W/yer_not_workin( 5318): Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (greylist, reflection, allowed)
29I/ExoPlayerImpl( 5318): Init d52da73 [ExoPlayerLib/2.14.1] [generic_x86_64_arm64, sdk_gphone_x86_64_arm64, Google, 30]
30I/Choreographer( 5318): Skipped 47 frames! The application may be doing too much work on its main thread.
31I/TetheringManager( 5318): registerTetheringEventCallback:com.example.video_player_not_working
32I/VideoCapabilities( 5318): Unsupported profile 4 for video/mp4v-es
33I/OMXClient( 5318): IOmx service obtained
34The Flutter DevTools debugger and profiler on sdk gphone x86 64 arm64 is available at:
35http://127.0.0.1:9102?uri=http://127.0.0.1:51217/xDqrRJJJEMY=/
36D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface
37I/MediaCodec( 5318): [OMX.android.goldfish.h264.decoder] setting surface generation to 5445633
38D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
39D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
40E/ACodec ( 5318): [OMX.android.goldfish.h264.decoder] setPortMode on output to DynamicANWBuffer failed w/ err -1010
41I/ACodec ( 5318): codec does not support config priority (err -1010)
42D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
43D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
44D/SurfaceUtils( 5318): set up nativeWindow 0x70fcbf3cba60 for 1280x720, color 0x13, rotation 0, usage 0x1002900
45W/Gralloc4( 5318): allocator 3.x is not supported
46D/CCodec ( 5318): allocate(c2.android.aac.decoder)
47Lost connection to device.
48import 'dart:async';
49
50import 'package:flutter/material.dart';
51import 'package:video_player/video_player.dart';
52
53void main() => runApp(const VideoPlayerApp());
54
55class VideoPlayerApp extends StatelessWidget {
56 const VideoPlayerApp({Key? key}) : super(key: key);
57
58 @override
59 Widget build(BuildContext context) {
60 return const MaterialApp(
61 title: 'Video Player Demo',
62 home: VideoPlayerScreen(),
63 );
64 }
65}
66
67class VideoPlayerScreen extends StatefulWidget {
68 const VideoPlayerScreen({Key? key}) : super(key: key);
69
70 @override
71 _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
72}
73
74class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
75 late VideoPlayerController _controller;
76 late Future<void> _initializeVideoPlayerFuture;
77
78 @override
79 void initState() {
80 // Create and store the VideoPlayerController. The VideoPlayerController
81 // offers several different constructors to play videos from assets, files,
82 // or the internet.
83 _controller = VideoPlayerController.network(
84 'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
85 );
86
87 // Initialize the controller and store the Future for later use.
88 _initializeVideoPlayerFuture = _controller.initialize();
89
90 // Use the controller to loop the video.
91 _controller.setLooping(true);
92
93 super.initState();
94 }
95
96 @override
97 void dispose() {
98 // Ensure disposing of the VideoPlayerController to free up resources.
99 _controller.dispose();
100
101 super.dispose();
102 }
103
104 @override
105 Widget build(BuildContext context) {
106 return Scaffold(
107 appBar: AppBar(
108 title: const Text('Butterfly Video'),
109 ),
110 // Use a FutureBuilder to display a loading spinner while waiting for the
111 // VideoPlayerController to finish initializing.
112 body: FutureBuilder(
113 future: _initializeVideoPlayerFuture,
114 builder: (context, snapshot) {
115 if (snapshot.connectionState == ConnectionState.done) {
116 // If the VideoPlayerController has finished initialization, use
117 // the data it provides to limit the aspect ratio of the video.
118 return AspectRatio(
119 aspectRatio: _controller.value.aspectRatio,
120 // Use the VideoPlayer widget to display the video.
121 child: VideoPlayer(_controller),
122 );
123 } else {
124 // If the VideoPlayerController is still initializing, show a
125 // loading spinner.
126 return const Center(
127 child: CircularProgressIndicator(),
128 );
129 }
130 },
131 ),
132 floatingActionButton: FloatingActionButton(
133 onPressed: () {
134 // Wrap the play or pause in a call to `setState`. This ensures the
135 // correct icon is shown.
136 setState(() {
137 // If the video is playing, pause it.
138 if (_controller.value.isPlaying) {
139 _controller.pause();
140 } else {
141 // If the video is paused, play it.
142 _controller.play();
143 }
144 });
145 },
146 // Display the correct icon depending on the state of the player.
147 child: Icon(
148 _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
149 ),
150 ),
151 );
152 }
153}
154name: video_player_not_working
155description: A new Flutter project.
156
157# The following line prevents the package from being accidentally published to
158# pub.dev using `flutter pub publish`. This is preferred for private packages.
159publish_to: 'none' # Remove this line if you wish to publish to pub.dev
160
161# The following defines the version and build number for your application.
162# A version number is three numbers separated by dots, like 1.2.43
163# followed by an optional build number separated by a +.
164# Both the version and the builder number may be overridden in flutter
165# build by specifying --build-name and --build-number, respectively.
166# In Android, build-name is used as versionName while build-number used as versionCode.
167# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
168# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
169# Read more about iOS versioning at
170# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
171version: 1.0.0+1
172
173environment:
174 sdk: ">=2.15.1 <3.0.0"
175
176# Dependencies specify other packages that your package needs in order to work.
177# To automatically upgrade your package dependencies to the latest versions
178# consider running `flutter pub upgrade --major-versions`. Alternatively,
179# dependencies can be manually updated by changing the version numbers below to
180# the latest version available on pub.dev. To see which dependencies have newer
181# versions available, run `flutter pub outdated`.
182dependencies:
183 flutter:
184 sdk: flutter
185
186
187 # The following adds the Cupertino Icons font to your application.
188 # Use with the CupertinoIcons class for iOS style icons.
189 cupertino_icons: ^1.0.2
190 video_player: ^2.2.10
191
192dev_dependencies:
193 flutter_test:
194 sdk: flutter
195
196 # The "flutter_lints" package below contains a set of recommended lints to
197 # encourage good coding practices. The lint set provided by the package is
198 # activated in the `analysis_options.yaml` file located at the root of your
199 # package. See that file for information about deactivating specific lint
200 # rules and activating additional ones.
201 flutter_lints: ^1.0.0
202
203# For information on the generic Dart part of this file, see the
204# following page: https://dart.dev/tools/pub/pubspec
205
206# The following section is specific to Flutter.
207flutter:
208
209 # The following line ensures that the Material Icons font is
210 # included with your application, so that you can use the icons in
211 # the material Icons class.
212 uses-material-design: true
213
214 # To add assets to your application, add an assets section, like this:
215 # assets:
216 # - images/a_dot_burr.jpeg
217 # - images/a_dot_ham.jpeg
218
219 # An image asset can refer to one or more resolution-specific "variants", see
220 # https://flutter.dev/assets-and-images/#resolution-aware.
221
222 # For details regarding adding assets from package dependencies, see
223 # https://flutter.dev/assets-and-images/#from-packages
224
225 # To add custom fonts to your application, add a fonts section here,
226 # in this "flutter" section. Each entry in this list should have a
227 # "family" key with the font family name, and a "fonts" key with a
228 # list giving the asset and other descriptors for the font. For
229 # example:
230 # fonts:
231 # - family: Schyler
232 # fonts:
233 # - asset: fonts/Schyler-Regular.ttf
234 # - asset: fonts/Schyler-Italic.ttf
235 # style: italic
236 # - family: Trajan Pro
237 # fonts:
238 # - asset: fonts/TrajanPro.ttf
239 # - asset: fonts/TrajanPro_Bold.ttf
240 # weight: 700
241 #
242 # For details regarding fonts from package dependencies,
243 # see https://flutter.dev/custom-fonts/#from-packages
244<manifest xmlns:android="http://schemas.android.com/apk/res/android"
245 package="com.example.video_player_not_working">
246 <application
247 android:label="video_player_not_working"
248 android:name="${applicationName}"
249 android:icon="@mipmap/ic_launcher">
250 <activity
251 android:name=".MainActivity"
252 android:exported="true"
253 android:launchMode="singleTop"
254 android:theme="@style/LaunchTheme"
255 android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
256 android:hardwareAccelerated="true"
257 android:windowSoftInputMode="adjustResize">
258 <!-- Specifies an Android theme to apply to this Activity as soon as
259 the Android process has started. This theme is visible to the user
260 while the Flutter UI initializes. After that, this theme continues
261 to determine the Window background behind the Flutter UI. -->
262 <meta-data
263 android:name="io.flutter.embedding.android.NormalTheme"
264 android:resource="@style/NormalTheme"
265 />
266 <intent-filter>
267 <action android:name="android.intent.action.MAIN"/>
268 <category android:name="android.intent.category.LAUNCHER"/>
269 </intent-filter>
270 </activity>
271 <!-- Don't delete the meta-data below.
272 This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
273 <meta-data
274 android:name="flutterEmbedding"
275 android:value="2" />
276 </application>
277 <uses-permission android:name="android.permission.INTERNET"/>
278</manifest>
279
Output of flutter doctor -v
:
1~\OneDrive\Documents\Coding\Flutter\video_player_not_working> flutter run
2Using hardware rendering with device sdk gphone x86 64 arm64. If you notice graphics artifacts, consider enabling software
3rendering with "--enable-software-rendering".
4Launching lib\main.dart on sdk gphone x86 64 arm64 in debug mode...
5Checking the license for package Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\licenses
6License for package Android SDK Platform 31 accepted.
7Preparing "Install Android SDK Platform 31 (revision: 1)".
8"Install Android SDK Platform 31 (revision: 1)" ready.
9Installing Android SDK Platform 31 in C:\Users\ketha\AppData\Local\Android\Sdk\platforms\android-31
10"Install Android SDK Platform 31 (revision: 1)" complete.
11"Install Android SDK Platform 31 (revision: 1)" finished.
12Running Gradle task 'assembleDebug'... 153.4s
13√ Built build\app\outputs\flutter-apk\app-debug.apk.
14Installing build\app\outputs\flutter-apk\app.apk... 2,093ms
15Syncing files to device sdk gphone x86 64 arm64... 292ms
16
17Flutter run key commands.
18r Hot reload.
19R Hot restart.
20h List all available interactive commands.
21d Detach (terminate "flutter run" but leave application running).
22c Clear the screen
23q Quit (terminate the application on the device).
24
25 Running with sound null safety
26
27An Observatory debugger and profiler on sdk gphone x86 64 arm64 is available at: http://127.0.0.1:51217/xDqrRJJJEMY=/
28W/yer_not_workin( 5318): Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (greylist, reflection, allowed)
29I/ExoPlayerImpl( 5318): Init d52da73 [ExoPlayerLib/2.14.1] [generic_x86_64_arm64, sdk_gphone_x86_64_arm64, Google, 30]
30I/Choreographer( 5318): Skipped 47 frames! The application may be doing too much work on its main thread.
31I/TetheringManager( 5318): registerTetheringEventCallback:com.example.video_player_not_working
32I/VideoCapabilities( 5318): Unsupported profile 4 for video/mp4v-es
33I/OMXClient( 5318): IOmx service obtained
34The Flutter DevTools debugger and profiler on sdk gphone x86 64 arm64 is available at:
35http://127.0.0.1:9102?uri=http://127.0.0.1:51217/xDqrRJJJEMY=/
36D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface
37I/MediaCodec( 5318): [OMX.android.goldfish.h264.decoder] setting surface generation to 5445633
38D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
39D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason connectToSurface(reconnect)
40E/ACodec ( 5318): [OMX.android.goldfish.h264.decoder] setPortMode on output to DynamicANWBuffer failed w/ err -1010
41I/ACodec ( 5318): codec does not support config priority (err -1010)
42D/SurfaceUtils( 5318): disconnecting from surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
43D/SurfaceUtils( 5318): connecting to surface 0x70fcbf3cba60, reason setNativeWindowSizeFormatAndUsage
44D/SurfaceUtils( 5318): set up nativeWindow 0x70fcbf3cba60 for 1280x720, color 0x13, rotation 0, usage 0x1002900
45W/Gralloc4( 5318): allocator 3.x is not supported
46D/CCodec ( 5318): allocate(c2.android.aac.decoder)
47Lost connection to device.
48import 'dart:async';
49
50import 'package:flutter/material.dart';
51import 'package:video_player/video_player.dart';
52
53void main() => runApp(const VideoPlayerApp());
54
55class VideoPlayerApp extends StatelessWidget {
56 const VideoPlayerApp({Key? key}) : super(key: key);
57
58 @override
59 Widget build(BuildContext context) {
60 return const MaterialApp(
61 title: 'Video Player Demo',
62 home: VideoPlayerScreen(),
63 );
64 }
65}
66
67class VideoPlayerScreen extends StatefulWidget {
68 const VideoPlayerScreen({Key? key}) : super(key: key);
69
70 @override
71 _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
72}
73
74class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
75 late VideoPlayerController _controller;
76 late Future<void> _initializeVideoPlayerFuture;
77
78 @override
79 void initState() {
80 // Create and store the VideoPlayerController. The VideoPlayerController
81 // offers several different constructors to play videos from assets, files,
82 // or the internet.
83 _controller = VideoPlayerController.network(
84 'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
85 );
86
87 // Initialize the controller and store the Future for later use.
88 _initializeVideoPlayerFuture = _controller.initialize();
89
90 // Use the controller to loop the video.
91 _controller.setLooping(true);
92
93 super.initState();
94 }
95
96 @override
97 void dispose() {
98 // Ensure disposing of the VideoPlayerController to free up resources.
99 _controller.dispose();
100
101 super.dispose();
102 }
103
104 @override
105 Widget build(BuildContext context) {
106 return Scaffold(
107 appBar: AppBar(
108 title: const Text('Butterfly Video'),
109 ),
110 // Use a FutureBuilder to display a loading spinner while waiting for the
111 // VideoPlayerController to finish initializing.
112 body: FutureBuilder(
113 future: _initializeVideoPlayerFuture,
114 builder: (context, snapshot) {
115 if (snapshot.connectionState == ConnectionState.done) {
116 // If the VideoPlayerController has finished initialization, use
117 // the data it provides to limit the aspect ratio of the video.
118 return AspectRatio(
119 aspectRatio: _controller.value.aspectRatio,
120 // Use the VideoPlayer widget to display the video.
121 child: VideoPlayer(_controller),
122 );
123 } else {
124 // If the VideoPlayerController is still initializing, show a
125 // loading spinner.
126 return const Center(
127 child: CircularProgressIndicator(),
128 );
129 }
130 },
131 ),
132 floatingActionButton: FloatingActionButton(
133 onPressed: () {
134 // Wrap the play or pause in a call to `setState`. This ensures the
135 // correct icon is shown.
136 setState(() {
137 // If the video is playing, pause it.
138 if (_controller.value.isPlaying) {
139 _controller.pause();
140 } else {
141 // If the video is paused, play it.
142 _controller.play();
143 }
144 });
145 },
146 // Display the correct icon depending on the state of the player.
147 child: Icon(
148 _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
149 ),
150 ),
151 );
152 }
153}
154name: video_player_not_working
155description: A new Flutter project.
156
157# The following line prevents the package from being accidentally published to
158# pub.dev using `flutter pub publish`. This is preferred for private packages.
159publish_to: 'none' # Remove this line if you wish to publish to pub.dev
160
161# The following defines the version and build number for your application.
162# A version number is three numbers separated by dots, like 1.2.43
163# followed by an optional build number separated by a +.
164# Both the version and the builder number may be overridden in flutter
165# build by specifying --build-name and --build-number, respectively.
166# In Android, build-name is used as versionName while build-number used as versionCode.
167# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
168# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
169# Read more about iOS versioning at
170# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
171version: 1.0.0+1
172
173environment:
174 sdk: ">=2.15.1 <3.0.0"
175
176# Dependencies specify other packages that your package needs in order to work.
177# To automatically upgrade your package dependencies to the latest versions
178# consider running `flutter pub upgrade --major-versions`. Alternatively,
179# dependencies can be manually updated by changing the version numbers below to
180# the latest version available on pub.dev. To see which dependencies have newer
181# versions available, run `flutter pub outdated`.
182dependencies:
183 flutter:
184 sdk: flutter
185
186
187 # The following adds the Cupertino Icons font to your application.
188 # Use with the CupertinoIcons class for iOS style icons.
189 cupertino_icons: ^1.0.2
190 video_player: ^2.2.10
191
192dev_dependencies:
193 flutter_test:
194 sdk: flutter
195
196 # The "flutter_lints" package below contains a set of recommended lints to
197 # encourage good coding practices. The lint set provided by the package is
198 # activated in the `analysis_options.yaml` file located at the root of your
199 # package. See that file for information about deactivating specific lint
200 # rules and activating additional ones.
201 flutter_lints: ^1.0.0
202
203# For information on the generic Dart part of this file, see the
204# following page: https://dart.dev/tools/pub/pubspec
205
206# The following section is specific to Flutter.
207flutter:
208
209 # The following line ensures that the Material Icons font is
210 # included with your application, so that you can use the icons in
211 # the material Icons class.
212 uses-material-design: true
213
214 # To add assets to your application, add an assets section, like this:
215 # assets:
216 # - images/a_dot_burr.jpeg
217 # - images/a_dot_ham.jpeg
218
219 # An image asset can refer to one or more resolution-specific "variants", see
220 # https://flutter.dev/assets-and-images/#resolution-aware.
221
222 # For details regarding adding assets from package dependencies, see
223 # https://flutter.dev/assets-and-images/#from-packages
224
225 # To add custom fonts to your application, add a fonts section here,
226 # in this "flutter" section. Each entry in this list should have a
227 # "family" key with the font family name, and a "fonts" key with a
228 # list giving the asset and other descriptors for the font. For
229 # example:
230 # fonts:
231 # - family: Schyler
232 # fonts:
233 # - asset: fonts/Schyler-Regular.ttf
234 # - asset: fonts/Schyler-Italic.ttf
235 # style: italic
236 # - family: Trajan Pro
237 # fonts:
238 # - asset: fonts/TrajanPro.ttf
239 # - asset: fonts/TrajanPro_Bold.ttf
240 # weight: 700
241 #
242 # For details regarding fonts from package dependencies,
243 # see https://flutter.dev/custom-fonts/#from-packages
244<manifest xmlns:android="http://schemas.android.com/apk/res/android"
245 package="com.example.video_player_not_working">
246 <application
247 android:label="video_player_not_working"
248 android:name="${applicationName}"
249 android:icon="@mipmap/ic_launcher">
250 <activity
251 android:name=".MainActivity"
252 android:exported="true"
253 android:launchMode="singleTop"
254 android:theme="@style/LaunchTheme"
255 android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
256 android:hardwareAccelerated="true"
257 android:windowSoftInputMode="adjustResize">
258 <!-- Specifies an Android theme to apply to this Activity as soon as
259 the Android process has started. This theme is visible to the user
260 while the Flutter UI initializes. After that, this theme continues
261 to determine the Window background behind the Flutter UI. -->
262 <meta-data
263 android:name="io.flutter.embedding.android.NormalTheme"
264 android:resource="@style/NormalTheme"
265 />
266 <intent-filter>
267 <action android:name="android.intent.action.MAIN"/>
268 <category android:name="android.intent.category.LAUNCHER"/>
269 </intent-filter>
270 </activity>
271 <!-- Don't delete the meta-data below.
272 This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
273 <meta-data
274 android:name="flutterEmbedding"
275 android:value="2" />
276 </application>
277 <uses-permission android:name="android.permission.INTERNET"/>
278</manifest>
279~\OneDrive\Documents\Coding\Flutter\video_player_not_working> flutter doctor -v
280[√] Flutter (Channel stable, 2.8.1, on Microsoft Windows [Version 10.0.22000.376], locale en-US)
281 • Flutter version 2.8.1 at C:\tools\flutter
282 • Upstream repository https://github.com/flutter/flutter.git
283 • Framework revision 77d935af4d (2 weeks ago), 2021-12-16 08:37:33 -0800
284 • Engine revision 890a5fca2e
285 • Dart version 2.15.1
286
287[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
288 • Android SDK at C:\Users\ketha\AppData\Local\Android\Sdk
289 • Platform android-31, build-tools 30.0.3
290 • ANDROID_HOME = C:\Users\ketha\AppData\Local\Android\Sdk
291 • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
292 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
293 • All Android licenses accepted.
294
295[√] Chrome - develop for the web
296 • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
297
298[√] Android Studio (version 4.1)
299 • Android Studio at C:\Program Files\Android\Android Studio
300 • Flutter plugin can be installed from:
301 https://plugins.jetbrains.com/plugin/9212-flutter
302 • Dart plugin can be installed from:
303 https://plugins.jetbrains.com/plugin/6351-dart
304 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
305
306[√] VS Code (version 1.63.2)
307 • VS Code at C:\Users\ketha\AppData\Local\Programs\Microsoft VS Code
308 • Flutter extension version 3.29.0
309
310[√] Connected device (3 available)
311 • sdk gphone x86 64 arm64 (mobile) • emulator-5554 • android-x64 • Android 11 (API 30) (emulator)
312 • Chrome (web) • chrome • web-javascript • Google Chrome 96.0.4664.110
313 • Edge (web) • edge • web-javascript • Microsoft Edge 96.0.1054.62
314
315• No issues found!
316
ANSWER
Answered 2022-Jan-11 at 08:53It can be a bug of that Flutter package, indeed. Have you tried to create an issue in GitHub of that package?
Secondly, during my development, I see several times when emulators just fail and real devices always work. The solution I used is - simply to do not test them on simulators. Real users never use simulators, aren't they?
It can be a bug of the library when running on x86 arch (the arch simulators use). Then, nobody with a real device (arm arch) will ever see the bug.
Thirdly, what about trying to use "cloud real devices" to test whether they work on real Pixel devices that you are worried about. There are many platforms that host some real devices and you can connect to them via a webpage and test your app.
QUESTION
How to detect the length of array property using reflection only if it actually is an array?
Asked 2022-Jan-02 at 11:43I'm converting an object based on reflection like this.
1obj.GetType().GetProperties()
2
It produces the expected list of properties.
{System.Reflection.PropertyInfo[4]}
[0]: {System.String Name}
[1]: {System.Guid[] Ids}
[2]: {System.String[] Tags}
[3]: {System.Nullable`1[System.Boolean] Status}
Then, I want to clear the list of properties not in use, so I add the condition that a value of a property needs to differ from null
.
1obj.GetType().GetProperties()
2obj.GetType().GetProperties()
3 .Where(a => a.GetValue(obj) != null)
4
It produces the expected result for atomary fields but not the arrays (as they're undefinably not null
, only empty).
{System.Linq.Enumerable.WhereArrayIterator<System.Reflection.PropertyInfo>}
[0]: {System.String Name}
[1]: {System.Guid[] Ids}
[2]: {System.String[] Tags}
I'm not sure how I should go about detecting non-null but empty array properties in order to exclude those. I can't simply cast to an array (as discussed here) because not every property is an array.
The closest approach I have is this piece of "work", which seems to be rather... undesired. It's got this distinct code smell going on.
1obj.GetType().GetProperties()
2obj.GetType().GetProperties()
3 .Where(a => a.GetValue(obj) != null)
4obj.GetType().GetProperties()
5 .Where(a => a.GetValue(obj) != null
6 && !(a.GetValue(obj) is Array && (a.GetValue(obj) as Array).Length == 0))
7
And as I try to create something with it using Select(a=>a.GetValue(obj))
it gets even clunkier and more obviously in desperate need of improvement. I also noticed that whenever the array isn't empty, my mapping fails producing System.String%5b%5d
, which will probably require me to additionally clunkify the code.
ANSWER
Answered 2022-Jan-01 at 18:01I can't think of a solution that's significantly different to yours, fundamentally it feels like it's a custom logic to determine whether a property value is "empty" or not.
Perhaps a pattern matched switch expression might make the code a little cleaner, however, for example:
1obj.GetType().GetProperties()
2obj.GetType().GetProperties()
3 .Where(a => a.GetValue(obj) != null)
4obj.GetType().GetProperties()
5 .Where(a => a.GetValue(obj) != null
6 && !(a.GetValue(obj) is Array && (a.GetValue(obj) as Array).Length == 0))
7var obj = new MyObject
8{
9 Name = "Test",
10 Ids = new Guid[0],
11 Tags = new[] { "t1" },
12 Status = null
13};
14
15var values = obj.GetType().GetProperties()
16 .Select(p => p.GetValue(obj))
17 .Where(o => o switch {
18 Array array => array.Length > 0,
19 _ => o != null
20 });
21
QUESTION
How do I replace a switch statement over an enum with runtime-dynamic type-based generic dispatch in C#?
Asked 2021-Dec-30 at 16:43Background:
I am building an editor extension for Unity (although this question is not strictly unity related). The user can select a binary operation from a dropdown and the operation is performed on the inputs, as seen in the diagram:
The code is taken from a tutorial, and uses an enum here in combination with a switch statement here to achieve the desired behavior.
This next image demonstrates the relationship between the code and the behavior in the graph UI:
Problem
Based on my prior experience programming in other languages, and my desire to allow for user-extensible operations that don't require users to edit a switch statement in the core code, I would LIKE the resulting code to look something like this (invalid) C# code:
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25
Reference Behavior To be crystal clear about the kind of behavior I'm hoping to achieve, here is a reference implementation in Python.
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44
Specific Questions So ultimately this boils down to three interrelated questions:
What sort of type do I assign to
MathOperations
so that it can hold a collection of the subtypes ofGenericOperation
?How do I get the subtypes of
GenericOperation
?What type do I assign
operation
, which can be one of several types?
Work So Far
I have been looking into generics and reflection from some of the following sources, but so far none seem to provide exactly the information I'm looking for.
- https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics
- https://igoro.com/archive/fun-with-c-generics-down-casting-to-a-generic-type/
- Using enum as generic type parameter in C#
- https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generics-and-reflection
Edit: I edited the comments in the C# psuedocode to reflect that the primary confusion boils down to what the types should be for MathOperations
and operation
, and to note that the editor itself selects the operation
from the MathOperations
when the user clicks on the dropdown. I also changed the question so that they can be answered factually.
ANSWER
Answered 2021-Dec-30 at 16:43Usually I'd say your question is quite broad and the use case very tricky and requires a lot of not so trivial steps to approach. But I see you also have put quite an effort in research and your question so I'll try to do the same (little Christmas Present) ;)
In general I think generics is not what you want to use here. Generics always require compile time constant parameters.
As I am only on the phone and don't know I can't give you a full solution right now but I hope I can bring you into the right track.
1. Common Interface or base class
I think the simplest thing would rather be a common interface such as e.g.
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48
A common abstract
base class would of course do as well. (You could even go for a certain attribute on methods)
And then have some implementations such as e.g.
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64
2. Find all implementations using Reflection
You can then use Reflection (you already were on the right track there) in order to automatically find all available implementations of that interface like e.g. this
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73
3. Store/Serialize a selected type in Unity
Now you have all the types ...
However, in order to really use these within Unity you will need an additional special class that is [Serializable]
and can store a type e.g. like
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73[Serializable]
74// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
75public class SerializableType : ISerializationCallbackReceiver
76{
77 private Type type;
78 [SerializeField] private string typeName;
79
80 public Type Type => type;
81
82 public void OnBeforeSerialize()
83 {
84 typeName = type != null ? type.AssemblyQualifiedName : "";
85 }
86
87 public void OnAfterDeserialize()
88 {
89 if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
90 }
91}
92
4. Interface type selection and drawing the drop-down
Then since you don't want to type the names manually you would need a special drawer for the drop down menu with the given types that implement your interface (you see we are connecting the dots).
I would probably use an attribute like e.g.
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73[Serializable]
74// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
75public class SerializableType : ISerializationCallbackReceiver
76{
77 private Type type;
78 [SerializeField] private string typeName;
79
80 public Type Type => type;
81
82 public void OnBeforeSerialize()
83 {
84 typeName = type != null ? type.AssemblyQualifiedName : "";
85 }
86
87 public void OnAfterDeserialize()
88 {
89 if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
90 }
91}
92[AttributeUsage(AttributeTarget.Field)]
93public ImplementsAttribute : PropertyAttribute
94{
95 public Type baseType;
96
97 public ImplementsAttribute (Type type)
98 {
99 baseType = type;
100 }
101}
102
You could then expose the field as e.g.
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73[Serializable]
74// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
75public class SerializableType : ISerializationCallbackReceiver
76{
77 private Type type;
78 [SerializeField] private string typeName;
79
80 public Type Type => type;
81
82 public void OnBeforeSerialize()
83 {
84 typeName = type != null ? type.AssemblyQualifiedName : "";
85 }
86
87 public void OnAfterDeserialize()
88 {
89 if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
90 }
91}
92[AttributeUsage(AttributeTarget.Field)]
93public ImplementsAttribute : PropertyAttribute
94{
95 public Type baseType;
96
97 public ImplementsAttribute (Type type)
98 {
99 baseType = type;
100 }
101}
102[Implements(typeof (ITwoFloatOperation))]
103public SerializableType operationType;
104
and then have a custom drawer. This depends of course on your needs. Honestly my editor scripting knowledge is more based on MonoBehaviour etc so I just hope you can somehow translate this into your graph thingy.
Something like e.g.
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73[Serializable]
74// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
75public class SerializableType : ISerializationCallbackReceiver
76{
77 private Type type;
78 [SerializeField] private string typeName;
79
80 public Type Type => type;
81
82 public void OnBeforeSerialize()
83 {
84 typeName = type != null ? type.AssemblyQualifiedName : "";
85 }
86
87 public void OnAfterDeserialize()
88 {
89 if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
90 }
91}
92[AttributeUsage(AttributeTarget.Field)]
93public ImplementsAttribute : PropertyAttribute
94{
95 public Type baseType;
96
97 public ImplementsAttribute (Type type)
98 {
99 baseType = type;
100 }
101}
102[Implements(typeof (ITwoFloatOperation))]
103public SerializableType operationType;
104 [CustomPropertyDrawer(typeof(ImplementsAttribute))]
105public class ImplementsDrawer : PropertyDrawer
106{
107 // Return the underlying type of s serialized property
108 private static Type GetType(SerializedProperty property)
109 {
110 // A little bit hacky we first get the type of the object that has this field
111 var parentType = property.serializedObject.targetObject.GetType();
112 // And then once again we use reflection to get the field via it's name again
113 var fi = parentType.GetField(property.propertyPath);
114 return fi.FieldType;
115 }
116
117 private static Type[] FindTypes (Type baseType)
118 {
119 var type = typeof(ITwoFloatOperation);
120 var types = AppDomain.CurrentDomain.GetAssemblies()
121 .SelectMany(s => s.GetTypes())
122 .Where(p => type.IsAssignableFrom(p));
123
124 return types.OrderBy(t => t.AssemblyQualifiedName).ToArray();
125 }
126
127 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
128 {
129 label = EditorGUI.BeginProperty(position, label, property);
130
131 var implements = attribute as ImplementsAttribute;
132
133 if (GetType(property) != typeof (SerializableType))
134 {
135 EditorGUI.HelpBox(position, MessageType.Error, "Implements only works for SerializableType!");
136 return;
137 }
138
139 var typeNameProperty = property.FindPropertyRelative("typeName");
140
141 var options = FindTypes (implements.baseType);
142
143 var guiOptions = options.Select(o => o.AssemblyQualifiedName).ToArray();
144
145 var currentType = string.IsNullOrWhiteSpace(typeNameProperty.stringValue) ? null : Type.GetType(typeNameProperty.stringValue);
146
147 var currentIndex = options.FindIndex(o => o == curtentType);
148
149 var newIndex = EditorGUI.Popup(position, label.text, currentIndex, guiOptions);
150
151 var newTypeName = newIndex >= 0 ? options[newIndex] : "";
152
153 property.stringValue = newTypeName;
154 EditorGUI.EndProperty();
155 }
156}
157
5. Using the type to create an instance
Once you somehow can store and get the desired type as a last step we want to use it ^^
Again the solution would be reflection and the Activator
which allows us to create an instance of any given dynamic type using Activator.CreateInstance
so once you have the field you would e.g. do
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73[Serializable]
74// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
75public class SerializableType : ISerializationCallbackReceiver
76{
77 private Type type;
78 [SerializeField] private string typeName;
79
80 public Type Type => type;
81
82 public void OnBeforeSerialize()
83 {
84 typeName = type != null ? type.AssemblyQualifiedName : "";
85 }
86
87 public void OnAfterDeserialize()
88 {
89 if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
90 }
91}
92[AttributeUsage(AttributeTarget.Field)]
93public ImplementsAttribute : PropertyAttribute
94{
95 public Type baseType;
96
97 public ImplementsAttribute (Type type)
98 {
99 baseType = type;
100 }
101}
102[Implements(typeof (ITwoFloatOperation))]
103public SerializableType operationType;
104 [CustomPropertyDrawer(typeof(ImplementsAttribute))]
105public class ImplementsDrawer : PropertyDrawer
106{
107 // Return the underlying type of s serialized property
108 private static Type GetType(SerializedProperty property)
109 {
110 // A little bit hacky we first get the type of the object that has this field
111 var parentType = property.serializedObject.targetObject.GetType();
112 // And then once again we use reflection to get the field via it's name again
113 var fi = parentType.GetField(property.propertyPath);
114 return fi.FieldType;
115 }
116
117 private static Type[] FindTypes (Type baseType)
118 {
119 var type = typeof(ITwoFloatOperation);
120 var types = AppDomain.CurrentDomain.GetAssemblies()
121 .SelectMany(s => s.GetTypes())
122 .Where(p => type.IsAssignableFrom(p));
123
124 return types.OrderBy(t => t.AssemblyQualifiedName).ToArray();
125 }
126
127 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
128 {
129 label = EditorGUI.BeginProperty(position, label, property);
130
131 var implements = attribute as ImplementsAttribute;
132
133 if (GetType(property) != typeof (SerializableType))
134 {
135 EditorGUI.HelpBox(position, MessageType.Error, "Implements only works for SerializableType!");
136 return;
137 }
138
139 var typeNameProperty = property.FindPropertyRelative("typeName");
140
141 var options = FindTypes (implements.baseType);
142
143 var guiOptions = options.Select(o => o.AssemblyQualifiedName).ToArray();
144
145 var currentType = string.IsNullOrWhiteSpace(typeNameProperty.stringValue) ? null : Type.GetType(typeNameProperty.stringValue);
146
147 var currentIndex = options.FindIndex(o => o == curtentType);
148
149 var newIndex = EditorGUI.Popup(position, label.text, currentIndex, guiOptions);
150
151 var newTypeName = newIndex >= 0 ? options[newIndex] : "";
152
153 property.stringValue = newTypeName;
154 EditorGUI.EndProperty();
155 }
156}
157var instance = (ITwoFloatOperation) Activator.CreateInstance(operationType.Type));
158var result = instance.GetResult(floatA, floatB);
159
Once all this is setup an working correctly ( ^^ ) your "users"/developers can add new operations as simple as implementing your interface.
Alternative Approach - "Scriptable Behaviors"
Thinking about it further I think I have another - maybe a bit more simple approach.
This option is maybe not what you were targeting originally and is not a drop-down but we will rather simply use the already existing object selection popup for assets!
You could use something I like to call "Scriptable Behaviours" and have a base ScriptableObject
like
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73[Serializable]
74// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
75public class SerializableType : ISerializationCallbackReceiver
76{
77 private Type type;
78 [SerializeField] private string typeName;
79
80 public Type Type => type;
81
82 public void OnBeforeSerialize()
83 {
84 typeName = type != null ? type.AssemblyQualifiedName : "";
85 }
86
87 public void OnAfterDeserialize()
88 {
89 if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
90 }
91}
92[AttributeUsage(AttributeTarget.Field)]
93public ImplementsAttribute : PropertyAttribute
94{
95 public Type baseType;
96
97 public ImplementsAttribute (Type type)
98 {
99 baseType = type;
100 }
101}
102[Implements(typeof (ITwoFloatOperation))]
103public SerializableType operationType;
104 [CustomPropertyDrawer(typeof(ImplementsAttribute))]
105public class ImplementsDrawer : PropertyDrawer
106{
107 // Return the underlying type of s serialized property
108 private static Type GetType(SerializedProperty property)
109 {
110 // A little bit hacky we first get the type of the object that has this field
111 var parentType = property.serializedObject.targetObject.GetType();
112 // And then once again we use reflection to get the field via it's name again
113 var fi = parentType.GetField(property.propertyPath);
114 return fi.FieldType;
115 }
116
117 private static Type[] FindTypes (Type baseType)
118 {
119 var type = typeof(ITwoFloatOperation);
120 var types = AppDomain.CurrentDomain.GetAssemblies()
121 .SelectMany(s => s.GetTypes())
122 .Where(p => type.IsAssignableFrom(p));
123
124 return types.OrderBy(t => t.AssemblyQualifiedName).ToArray();
125 }
126
127 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
128 {
129 label = EditorGUI.BeginProperty(position, label, property);
130
131 var implements = attribute as ImplementsAttribute;
132
133 if (GetType(property) != typeof (SerializableType))
134 {
135 EditorGUI.HelpBox(position, MessageType.Error, "Implements only works for SerializableType!");
136 return;
137 }
138
139 var typeNameProperty = property.FindPropertyRelative("typeName");
140
141 var options = FindTypes (implements.baseType);
142
143 var guiOptions = options.Select(o => o.AssemblyQualifiedName).ToArray();
144
145 var currentType = string.IsNullOrWhiteSpace(typeNameProperty.stringValue) ? null : Type.GetType(typeNameProperty.stringValue);
146
147 var currentIndex = options.FindIndex(o => o == curtentType);
148
149 var newIndex = EditorGUI.Popup(position, label.text, currentIndex, guiOptions);
150
151 var newTypeName = newIndex >= 0 ? options[newIndex] : "";
152
153 property.stringValue = newTypeName;
154 EditorGUI.EndProperty();
155 }
156}
157var instance = (ITwoFloatOperation) Activator.CreateInstance(operationType.Type));
158var result = instance.GetResult(floatA, floatB);
159public abstract class TwoFloatOperation : ScriptableObject
160{
161 public abstract float GetResult(float a, float b);
162}
163
And then multiple implementations (note: all these have to be in different files!)
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73[Serializable]
74// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
75public class SerializableType : ISerializationCallbackReceiver
76{
77 private Type type;
78 [SerializeField] private string typeName;
79
80 public Type Type => type;
81
82 public void OnBeforeSerialize()
83 {
84 typeName = type != null ? type.AssemblyQualifiedName : "";
85 }
86
87 public void OnAfterDeserialize()
88 {
89 if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
90 }
91}
92[AttributeUsage(AttributeTarget.Field)]
93public ImplementsAttribute : PropertyAttribute
94{
95 public Type baseType;
96
97 public ImplementsAttribute (Type type)
98 {
99 baseType = type;
100 }
101}
102[Implements(typeof (ITwoFloatOperation))]
103public SerializableType operationType;
104 [CustomPropertyDrawer(typeof(ImplementsAttribute))]
105public class ImplementsDrawer : PropertyDrawer
106{
107 // Return the underlying type of s serialized property
108 private static Type GetType(SerializedProperty property)
109 {
110 // A little bit hacky we first get the type of the object that has this field
111 var parentType = property.serializedObject.targetObject.GetType();
112 // And then once again we use reflection to get the field via it's name again
113 var fi = parentType.GetField(property.propertyPath);
114 return fi.FieldType;
115 }
116
117 private static Type[] FindTypes (Type baseType)
118 {
119 var type = typeof(ITwoFloatOperation);
120 var types = AppDomain.CurrentDomain.GetAssemblies()
121 .SelectMany(s => s.GetTypes())
122 .Where(p => type.IsAssignableFrom(p));
123
124 return types.OrderBy(t => t.AssemblyQualifiedName).ToArray();
125 }
126
127 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
128 {
129 label = EditorGUI.BeginProperty(position, label, property);
130
131 var implements = attribute as ImplementsAttribute;
132
133 if (GetType(property) != typeof (SerializableType))
134 {
135 EditorGUI.HelpBox(position, MessageType.Error, "Implements only works for SerializableType!");
136 return;
137 }
138
139 var typeNameProperty = property.FindPropertyRelative("typeName");
140
141 var options = FindTypes (implements.baseType);
142
143 var guiOptions = options.Select(o => o.AssemblyQualifiedName).ToArray();
144
145 var currentType = string.IsNullOrWhiteSpace(typeNameProperty.stringValue) ? null : Type.GetType(typeNameProperty.stringValue);
146
147 var currentIndex = options.FindIndex(o => o == curtentType);
148
149 var newIndex = EditorGUI.Popup(position, label.text, currentIndex, guiOptions);
150
151 var newTypeName = newIndex >= 0 ? options[newIndex] : "";
152
153 property.stringValue = newTypeName;
154 EditorGUI.EndProperty();
155 }
156}
157var instance = (ITwoFloatOperation) Activator.CreateInstance(operationType.Type));
158var result = instance.GetResult(floatA, floatB);
159public abstract class TwoFloatOperation : ScriptableObject
160{
161 public abstract float GetResult(float a, float b);
162}
163[CreateAssetMenu (fileName = "Add", menuName = "TwoFloatOperations/Add")]
164public class Add : TwoFloatOperation
165{
166 public float GetResult(float a, float b) => a + b;
167}
168
169[CreateAssetMenu (fileName = "Multiply", menuName = "TwoFloatOperations/Multiply")]
170public class Multiply : TwoFloatOperation
171{
172 public float GetResult(float a, float b) => a * b;
173}
174
175[CreateAssetMenu (fileName = "Power", menuName = "TwoFloatOperations/Power"]
176public class Power : TwoFloatOperation
177{
178 public float GetResult(float a, float b) Mathf.Pow(a, b);
179}
180
Then you create one instance of each vis the ProjectView
-> Right Click -> Create
-> TwoFloatOperations
Once you did this for each type you can simply expose a field of type
1... snip ...
2
3 // OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
4 // So it would represent a collection of types?
5 // so the confusion is primarily around what type this should be
6 public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
7
8 // this gets assigned by the editor when the user clicks
9 // the dropdown, but I'm unclear on what the type should
10 // be since it can be one of several types
11 // from the MathOperations collection
12 public Operation /* ?? */ operation;
13
14 public override object GetValue(NodePort port)
15 {
16 float a = GetInputValue<float>("a", this.a);
17 float b = GetInputValue<float>("b", this.b);
18 result = 0f;
19 result = operation(a, b);
20 return result;
21 }
22
23... snip ...
24
25class GenericOperation:
26
27 @classmethod
28 def get_operations(cls):
29 return cls.__subclasses__()
30
31
32class AddOperation(GenericOperation):
33
34 def __call__(self, a, b):
35 return a + b
36
37
38if __name__ == '__main__':
39 op = AddOperation()
40 res = op(1, 2)
41 print(res) # 3
42 print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
43
44public interface ITwoFloatOperation
45{
46 public float GetResult(float a, float b);
47}
48public class Add : ITwoFloatOperation
49{
50 public float GetResult(float a, float b) => a + b;
51}
52
53public class Multiply : ITwoFloatOperation
54{
55 public float GetResult(float a, float b) => a * b;
56}
57
58public class Power : ITwoFloatOperation
59{
60 public float GetResult(float a, float b) Mathf.Pow(a, b);
61}
62
63... etc
64using System.Reflection;
65using System.Linq;
66
67...
68
69var type = typeof(ITwoFloatOperation);
70var types = AppDomain.CurrentDomain.GetAssemblies()
71 .SelectMany(s => s.GetTypes())
72 .Where(p => type.IsAssignableFrom(p));
73[Serializable]
74// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
75public class SerializableType : ISerializationCallbackReceiver
76{
77 private Type type;
78 [SerializeField] private string typeName;
79
80 public Type Type => type;
81
82 public void OnBeforeSerialize()
83 {
84 typeName = type != null ? type.AssemblyQualifiedName : "";
85 }
86
87 public void OnAfterDeserialize()
88 {
89 if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
90 }
91}
92[AttributeUsage(AttributeTarget.Field)]
93public ImplementsAttribute : PropertyAttribute
94{
95 public Type baseType;
96
97 public ImplementsAttribute (Type type)
98 {
99 baseType = type;
100 }
101}
102[Implements(typeof (ITwoFloatOperation))]
103public SerializableType operationType;
104 [CustomPropertyDrawer(typeof(ImplementsAttribute))]
105public class ImplementsDrawer : PropertyDrawer
106{
107 // Return the underlying type of s serialized property
108 private static Type GetType(SerializedProperty property)
109 {
110 // A little bit hacky we first get the type of the object that has this field
111 var parentType = property.serializedObject.targetObject.GetType();
112 // And then once again we use reflection to get the field via it's name again
113 var fi = parentType.GetField(property.propertyPath);
114 return fi.FieldType;
115 }
116
117 private static Type[] FindTypes (Type baseType)
118 {
119 var type = typeof(ITwoFloatOperation);
120 var types = AppDomain.CurrentDomain.GetAssemblies()
121 .SelectMany(s => s.GetTypes())
122 .Where(p => type.IsAssignableFrom(p));
123
124 return types.OrderBy(t => t.AssemblyQualifiedName).ToArray();
125 }
126
127 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
128 {
129 label = EditorGUI.BeginProperty(position, label, property);
130
131 var implements = attribute as ImplementsAttribute;
132
133 if (GetType(property) != typeof (SerializableType))
134 {
135 EditorGUI.HelpBox(position, MessageType.Error, "Implements only works for SerializableType!");
136 return;
137 }
138
139 var typeNameProperty = property.FindPropertyRelative("typeName");
140
141 var options = FindTypes (implements.baseType);
142
143 var guiOptions = options.Select(o => o.AssemblyQualifiedName).ToArray();
144
145 var currentType = string.IsNullOrWhiteSpace(typeNameProperty.stringValue) ? null : Type.GetType(typeNameProperty.stringValue);
146
147 var currentIndex = options.FindIndex(o => o == curtentType);
148
149 var newIndex = EditorGUI.Popup(position, label.text, currentIndex, guiOptions);
150
151 var newTypeName = newIndex >= 0 ? options[newIndex] : "";
152
153 property.stringValue = newTypeName;
154 EditorGUI.EndProperty();
155 }
156}
157var instance = (ITwoFloatOperation) Activator.CreateInstance(operationType.Type));
158var result = instance.GetResult(floatA, floatB);
159public abstract class TwoFloatOperation : ScriptableObject
160{
161 public abstract float GetResult(float a, float b);
162}
163[CreateAssetMenu (fileName = "Add", menuName = "TwoFloatOperations/Add")]
164public class Add : TwoFloatOperation
165{
166 public float GetResult(float a, float b) => a + b;
167}
168
169[CreateAssetMenu (fileName = "Multiply", menuName = "TwoFloatOperations/Multiply")]
170public class Multiply : TwoFloatOperation
171{
172 public float GetResult(float a, float b) => a * b;
173}
174
175[CreateAssetMenu (fileName = "Power", menuName = "TwoFloatOperations/Power"]
176public class Power : TwoFloatOperation
177{
178 public float GetResult(float a, float b) Mathf.Pow(a, b);
179}
180public TwoFloatOperation operation;
181
and let Unity do all the reflection work to find instances which implement this in the assets.
You can simply click on the little dot next to the object field and Unity will list you all available options and you can even use the search bar to find one by name.
Advantage:
- No dirty, expensive and error prone reflection required
- Basically all based on already built-in functionality of the editor -> less worries with serialization etc
Disadvantage:
- This breaks a little with the actual concept behind
ScriptableObject
since usually there would be multiple instances with different settings, not only a single one - As you see your developers have to not only inherit a certain type but additionally add the
CreateAssetMenu
attribute and actually create an instance in order to be able to use it.
As said typing this on the phone but I hope this helps with your use case and gives you an idea of how I would approach this
QUESTION
java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
Asked 2021-Dec-24 at 10:49I am trying to update my SpringBoot maven project to Java 17.
1<maven.compiler.source>17</maven.compiler.source>
2<maven.compiler.target>17</maven.compiler.target>
3
I had working maven-jaxb2-plugin plugin defined which created java classes successfully from XSD files.
1<maven.compiler.source>17</maven.compiler.source>
2<maven.compiler.target>17</maven.compiler.target>
3<plugin>
4 <groupId>org.jvnet.jaxb2.maven2</groupId>
5 <artifactId>maven-jaxb2-plugin</artifactId>
6 <version>0.14.0</version>
7 <executions>
8 <execution>
9 <id>my_schema</id>
10 <phase>generate-sources</phase>
11 <goals>
12 <goal>generate</goal>
13 </goals>
14 <configuration>
15 <schemaDirectory>src/main/resources/my/files</schemaDirectory>
16 <schemaIncludes>
17 <include>*.xsd</include>
18 </schemaIncludes>
19 <bindingDirectory>src/main/resources/my/files</bindingDirectory>
20 <bindingIncludes>
21 <include>bindings.xml</include>
22 </bindingIncludes>
23 <args>
24 <arg>-extension</arg>
25 <arg>-Xnamespace-prefix</arg>
26 </args>
27 </configuration>
28 </execution>
29 </executions>
30</plugin>
31
But since the upgrade of java and the plugin I cannot do it.
I definied the necessary dependencies for the plugin:
1<maven.compiler.source>17</maven.compiler.source>
2<maven.compiler.target>17</maven.compiler.target>
3<plugin>
4 <groupId>org.jvnet.jaxb2.maven2</groupId>
5 <artifactId>maven-jaxb2-plugin</artifactId>
6 <version>0.14.0</version>
7 <executions>
8 <execution>
9 <id>my_schema</id>
10 <phase>generate-sources</phase>
11 <goals>
12 <goal>generate</goal>
13 </goals>
14 <configuration>
15 <schemaDirectory>src/main/resources/my/files</schemaDirectory>
16 <schemaIncludes>
17 <include>*.xsd</include>
18 </schemaIncludes>
19 <bindingDirectory>src/main/resources/my/files</bindingDirectory>
20 <bindingIncludes>
21 <include>bindings.xml</include>
22 </bindingIncludes>
23 <args>
24 <arg>-extension</arg>
25 <arg>-Xnamespace-prefix</arg>
26 </args>
27 </configuration>
28 </execution>
29 </executions>
30</plugin>
31<dependency>
32 <groupId>com.sun.xml.bind</groupId>
33 <artifactId>jaxb-core</artifactId>
34 <version>3.0.2</version>
35</dependency>
36<dependency>
37 <groupId>javax.xml.bind</groupId>
38 <artifactId>jaxb-api</artifactId>
39 <version>2.3.1</version>
40</dependency>
41<dependency>
42 <groupId>com.sun.xml.bind</groupId>
43 <artifactId>jaxb-impl</artifactId>
44 <version>3.0.2</version>
45</dependency>
46<dependency>
47 <groupId>javax.activation</groupId>
48 <artifactId>activation</artifactId>
49 <version>1.1.1</version>
50</dependency>
51<dependency>
52 <groupId>jakarta.xml.bind</groupId>
53 <artifactId>jakarta.xml.bind-api</artifactId>
54 <version>3.0.1</version>
55</dependency>
56
But I still receive an unknown error during maven build:
1<maven.compiler.source>17</maven.compiler.source>
2<maven.compiler.target>17</maven.compiler.target>
3<plugin>
4 <groupId>org.jvnet.jaxb2.maven2</groupId>
5 <artifactId>maven-jaxb2-plugin</artifactId>
6 <version>0.14.0</version>
7 <executions>
8 <execution>
9 <id>my_schema</id>
10 <phase>generate-sources</phase>
11 <goals>
12 <goal>generate</goal>
13 </goals>
14 <configuration>
15 <schemaDirectory>src/main/resources/my/files</schemaDirectory>
16 <schemaIncludes>
17 <include>*.xsd</include>
18 </schemaIncludes>
19 <bindingDirectory>src/main/resources/my/files</bindingDirectory>
20 <bindingIncludes>
21 <include>bindings.xml</include>
22 </bindingIncludes>
23 <args>
24 <arg>-extension</arg>
25 <arg>-Xnamespace-prefix</arg>
26 </args>
27 </configuration>
28 </execution>
29 </executions>
30</plugin>
31<dependency>
32 <groupId>com.sun.xml.bind</groupId>
33 <artifactId>jaxb-core</artifactId>
34 <version>3.0.2</version>
35</dependency>
36<dependency>
37 <groupId>javax.xml.bind</groupId>
38 <artifactId>jaxb-api</artifactId>
39 <version>2.3.1</version>
40</dependency>
41<dependency>
42 <groupId>com.sun.xml.bind</groupId>
43 <artifactId>jaxb-impl</artifactId>
44 <version>3.0.2</version>
45</dependency>
46<dependency>
47 <groupId>javax.activation</groupId>
48 <artifactId>activation</artifactId>
49 <version>1.1.1</version>
50</dependency>
51<dependency>
52 <groupId>jakarta.xml.bind</groupId>
53 <artifactId>jakarta.xml.bind-api</artifactId>
54 <version>3.0.1</version>
55</dependency>
56Oct 19, 2021 10:07:06 PM com.sun.xml.bind.v2.runtime.reflect.opt.Injector <clinit>
57SEVERE: null
58java.security.PrivilegedActionException: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
59 at java.base/java.security.AccessController.doPrivileged(AccessController.java:573)
60 at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:197)
61 at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:81)
62 at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:179)
63 at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:285)
64 at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.<init>(TransducedAccessor.java:235)
65 at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:175)
66 at com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl.calcTransducer(RuntimeClassInfoImpl.java:245)
67 at com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl.getTransducer(RuntimeClassInfoImpl.java:219)
68 at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTransducer(RuntimeModelBuilder.java:145)
69 at com.sun.xml.bind.v2.model.impl.SingleTypePropertyInfoImpl.getTransducer(SingleTypePropertyInfoImpl.java:140)
70 at com.sun.xml.bind.v2.model.impl.RuntimeAttributePropertyInfoImpl.link(RuntimeAttributePropertyInfoImpl.java:78)
71 at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.link(ClassInfoImpl.java:1272)
72 at com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl.link(RuntimeClassInfoImpl.java:197)
73 at com.sun.xml.bind.v2.model.impl.ModelBuilder.link(ModelBuilder.java:454)
74 at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.link(RuntimeModelBuilder.java:133)
75 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:469)
76 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:303)
77 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:139)
78 at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1156)
79 at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:165)
80 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
81 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
82 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
83 at java.base/java.lang.reflect.Method.invoke(Method.java:568)
84 at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:297)
85 at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:286)
86 at javax.xml.bind.ContextFinder.find(ContextFinder.java:409)
87 at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
88 at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
89 at com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo.getCustomizationContext(BindInfo.java:336)
90 at com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo.getCustomizationUnmarshaller(BindInfo.java:362)
91 at com.sun.tools.xjc.reader.xmlschema.bindinfo.AnnotationParserFactoryImpl$1.<init>(AnnotationParserFactoryImpl.java:85)
92 at com.sun.tools.xjc.reader.xmlschema.bindinfo.AnnotationParserFactoryImpl.create(AnnotationParserFactoryImpl.java:84)
93 at com.sun.xml.xsom.impl.parser.NGCCRuntimeEx.createAnnotationParser(NGCCRuntimeEx.java:401)
94 at com.sun.xml.xsom.impl.parser.state.annotation.action0(annotation.java:89)
95 at com.sun.xml.xsom.impl.parser.state.annotation.enterElement(annotation.java:114)
96 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
97 at com.sun.xml.xsom.impl.parser.state.NGCCHandler.spawnChildFromEnterElement(NGCCHandler.java:114)
98 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:317)
99 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
100 at com.sun.xml.xsom.impl.parser.state.NGCCHandler.revertToParentFromEnterElement(NGCCHandler.java:151)
101 at com.sun.xml.xsom.impl.parser.state.foreignAttributes.enterElement(foreignAttributes.java:91)
102 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
103 at com.sun.xml.xsom.impl.parser.state.NGCCHandler.spawnChildFromEnterElement(NGCCHandler.java:114)
104 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:229)
105 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
106 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:273)
107 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
108 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:309)
109 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
110 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:293)
111 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
112 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:221)
113 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
114 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:257)
115 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.startElement(NGCCRuntime.java:263)
116 at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
117 at com.sun.tools.xjc.util.SubtreeCutter.startElement(SubtreeCutter.java:108)
118 at com.sun.tools.xjc.reader.ExtensionBindingChecker.startElement(ExtensionBindingChecker.java:150)
119 at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
120 at com.sun.tools.xjc.reader.xmlschema.parser.IncorrectNamespaceURIChecker.startElement(IncorrectNamespaceURIChecker.java:128)
121 at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
122 at com.sun.tools.xjc.reader.xmlschema.parser.CustomizationContextChecker.startElement(CustomizationContextChecker.java:193)
123 at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
124 at com.sun.tools.xjc.reader.internalizer.DOMForestScanner$LocationResolver.startElement(DOMForestScanner.java:147)
125 at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:244)
126 at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:281)
127 at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:250)
128 at com.sun.xml.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:127)
129 at com.sun.tools.xjc.reader.internalizer.DOMForestScanner.scan(DOMForestScanner.java:92)
130 at com.sun.tools.xjc.reader.internalizer.DOMForestScanner.scan(DOMForestScanner.java:100)
131 at com.sun.tools.xjc.reader.internalizer.DOMForestParser.parse(DOMForestParser.java:104)
132 at com.sun.tools.xjc.ModelLoader$XMLSchemaParser.parse(ModelLoader.java:251)
133 at com.sun.xml.xsom.impl.parser.NGCCRuntimeEx.parseEntity(NGCCRuntimeEx.java:381)
134 at com.sun.xml.xsom.impl.parser.ParserContext.parse(ParserContext.java:128)
135 at com.sun.xml.xsom.parser.XSOMParser.parse(XSOMParser.java:171)
136 at com.sun.xml.xsom.parser.XSOMParser.parse(XSOMParser.java:160)
137 at com.sun.tools.xjc.ModelLoader.createXSOM(ModelLoader.java:516)
138 at com.sun.tools.xjc.ModelLoader.loadXMLSchema(ModelLoader.java:360)
139 at com.sun.tools.xjc.ModelLoader.load(ModelLoader.java:162)
140 at com.sun.tools.xjc.ModelLoader.load(ModelLoader.java:117)
141 at org.jvnet.mjiip.v_2_3.XJC23Mojo.loadModel(XJC23Mojo.java:50)
142 at org.jvnet.mjiip.v_2_3.XJC23Mojo.doExecute(XJC23Mojo.java:40)
143 at org.jvnet.mjiip.v_2_3.XJC23Mojo.doExecute(XJC23Mojo.java:28)
144 at org.jvnet.jaxb2.maven2.RawXJC2Mojo.doExecute(RawXJC2Mojo.java:478)
145 at org.jvnet.jaxb2.maven2.RawXJC2Mojo.execute(RawXJC2Mojo.java:320)
146 at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
147 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
148 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
149 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
150 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
151 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
152 at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
153 at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
154 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
155 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
156 at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
157 at org.apache.maven.cli.MavenCli.execute(MavenCli.java:957)
158 at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289)
159 at org.apache.maven.cli.MavenCli.main(MavenCli.java:193)
160 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
161 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
162 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
163 at java.base/java.lang.reflect.Method.invoke(Method.java:568)
164 at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
165 at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
166 at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
167 at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
168 at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
169Caused by: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
170 at java.base/java.lang.Class.getMethod(Class.java:2227)
171 at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:201)
172 at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:197)
173 at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
174 ... 109 more
175
And I cannot find any useful tipp on the web. Can anyone help me how to fix this issue?
ANSWER
Answered 2021-Oct-25 at 06:28It compiles, when you'll add jaxb-runtime
dependency, as below:
1<maven.compiler.source>17</maven.compiler.source>
2<maven.compiler.target>17</maven.compiler.target>
3<plugin>
4 <groupId>org.jvnet.jaxb2.maven2</groupId>
5 <artifactId>maven-jaxb2-plugin</artifactId>
6 <version>0.14.0</version>
7 <executions>
8 <execution>
9 <id>my_schema</id>
10 <phase>generate-sources</phase>
11 <goals>
12 <goal>generate</goal>
13 </goals>
14 <configuration>
15 <schemaDirectory>src/main/resources/my/files</schemaDirectory>
16 <schemaIncludes>
17 <include>*.xsd</include>
18 </schemaIncludes>
19 <bindingDirectory>src/main/resources/my/files</bindingDirectory>
20 <bindingIncludes>
21 <include>bindings.xml</include>
22 </bindingIncludes>
23 <args>
24 <arg>-extension</arg>
25 <arg>-Xnamespace-prefix</arg>
26 </args>
27 </configuration>
28 </execution>
29 </executions>
30</plugin>
31<dependency>
32 <groupId>com.sun.xml.bind</groupId>
33 <artifactId>jaxb-core</artifactId>
34 <version>3.0.2</version>
35</dependency>
36<dependency>
37 <groupId>javax.xml.bind</groupId>
38 <artifactId>jaxb-api</artifactId>
39 <version>2.3.1</version>
40</dependency>
41<dependency>
42 <groupId>com.sun.xml.bind</groupId>
43 <artifactId>jaxb-impl</artifactId>
44 <version>3.0.2</version>
45</dependency>
46<dependency>
47 <groupId>javax.activation</groupId>
48 <artifactId>activation</artifactId>
49 <version>1.1.1</version>
50</dependency>
51<dependency>
52 <groupId>jakarta.xml.bind</groupId>
53 <artifactId>jakarta.xml.bind-api</artifactId>
54 <version>3.0.1</version>
55</dependency>
56Oct 19, 2021 10:07:06 PM com.sun.xml.bind.v2.runtime.reflect.opt.Injector <clinit>
57SEVERE: null
58java.security.PrivilegedActionException: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
59 at java.base/java.security.AccessController.doPrivileged(AccessController.java:573)
60 at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:197)
61 at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:81)
62 at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:179)
63 at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:285)
64 at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.<init>(TransducedAccessor.java:235)
65 at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:175)
66 at com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl.calcTransducer(RuntimeClassInfoImpl.java:245)
67 at com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl.getTransducer(RuntimeClassInfoImpl.java:219)
68 at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTransducer(RuntimeModelBuilder.java:145)
69 at com.sun.xml.bind.v2.model.impl.SingleTypePropertyInfoImpl.getTransducer(SingleTypePropertyInfoImpl.java:140)
70 at com.sun.xml.bind.v2.model.impl.RuntimeAttributePropertyInfoImpl.link(RuntimeAttributePropertyInfoImpl.java:78)
71 at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.link(ClassInfoImpl.java:1272)
72 at com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl.link(RuntimeClassInfoImpl.java:197)
73 at com.sun.xml.bind.v2.model.impl.ModelBuilder.link(ModelBuilder.java:454)
74 at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.link(RuntimeModelBuilder.java:133)
75 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:469)
76 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:303)
77 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:139)
78 at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1156)
79 at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:165)
80 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
81 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
82 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
83 at java.base/java.lang.reflect.Method.invoke(Method.java:568)
84 at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:297)
85 at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:286)
86 at javax.xml.bind.ContextFinder.find(ContextFinder.java:409)
87 at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
88 at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
89 at com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo.getCustomizationContext(BindInfo.java:336)
90 at com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo.getCustomizationUnmarshaller(BindInfo.java:362)
91 at com.sun.tools.xjc.reader.xmlschema.bindinfo.AnnotationParserFactoryImpl$1.<init>(AnnotationParserFactoryImpl.java:85)
92 at com.sun.tools.xjc.reader.xmlschema.bindinfo.AnnotationParserFactoryImpl.create(AnnotationParserFactoryImpl.java:84)
93 at com.sun.xml.xsom.impl.parser.NGCCRuntimeEx.createAnnotationParser(NGCCRuntimeEx.java:401)
94 at com.sun.xml.xsom.impl.parser.state.annotation.action0(annotation.java:89)
95 at com.sun.xml.xsom.impl.parser.state.annotation.enterElement(annotation.java:114)
96 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
97 at com.sun.xml.xsom.impl.parser.state.NGCCHandler.spawnChildFromEnterElement(NGCCHandler.java:114)
98 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:317)
99 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
100 at com.sun.xml.xsom.impl.parser.state.NGCCHandler.revertToParentFromEnterElement(NGCCHandler.java:151)
101 at com.sun.xml.xsom.impl.parser.state.foreignAttributes.enterElement(foreignAttributes.java:91)
102 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
103 at com.sun.xml.xsom.impl.parser.state.NGCCHandler.spawnChildFromEnterElement(NGCCHandler.java:114)
104 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:229)
105 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
106 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:273)
107 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
108 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:309)
109 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
110 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:293)
111 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
112 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:221)
113 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.sendEnterElement(NGCCRuntime.java:422)
114 at com.sun.xml.xsom.impl.parser.state.Schema.enterElement(Schema.java:257)
115 at com.sun.xml.xsom.impl.parser.state.NGCCRuntime.startElement(NGCCRuntime.java:263)
116 at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
117 at com.sun.tools.xjc.util.SubtreeCutter.startElement(SubtreeCutter.java:108)
118 at com.sun.tools.xjc.reader.ExtensionBindingChecker.startElement(ExtensionBindingChecker.java:150)
119 at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
120 at com.sun.tools.xjc.reader.xmlschema.parser.IncorrectNamespaceURIChecker.startElement(IncorrectNamespaceURIChecker.java:128)
121 at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
122 at com.sun.tools.xjc.reader.xmlschema.parser.CustomizationContextChecker.startElement(CustomizationContextChecker.java:193)
123 at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
124 at com.sun.tools.xjc.reader.internalizer.DOMForestScanner$LocationResolver.startElement(DOMForestScanner.java:147)
125 at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:244)
126 at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:281)
127 at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:250)
128 at com.sun.xml.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:127)
129 at com.sun.tools.xjc.reader.internalizer.DOMForestScanner.scan(DOMForestScanner.java:92)
130 at com.sun.tools.xjc.reader.internalizer.DOMForestScanner.scan(DOMForestScanner.java:100)
131 at com.sun.tools.xjc.reader.internalizer.DOMForestParser.parse(DOMForestParser.java:104)
132 at com.sun.tools.xjc.ModelLoader$XMLSchemaParser.parse(ModelLoader.java:251)
133 at com.sun.xml.xsom.impl.parser.NGCCRuntimeEx.parseEntity(NGCCRuntimeEx.java:381)
134 at com.sun.xml.xsom.impl.parser.ParserContext.parse(ParserContext.java:128)
135 at com.sun.xml.xsom.parser.XSOMParser.parse(XSOMParser.java:171)
136 at com.sun.xml.xsom.parser.XSOMParser.parse(XSOMParser.java:160)
137 at com.sun.tools.xjc.ModelLoader.createXSOM(ModelLoader.java:516)
138 at com.sun.tools.xjc.ModelLoader.loadXMLSchema(ModelLoader.java:360)
139 at com.sun.tools.xjc.ModelLoader.load(ModelLoader.java:162)
140 at com.sun.tools.xjc.ModelLoader.load(ModelLoader.java:117)
141 at org.jvnet.mjiip.v_2_3.XJC23Mojo.loadModel(XJC23Mojo.java:50)
142 at org.jvnet.mjiip.v_2_3.XJC23Mojo.doExecute(XJC23Mojo.java:40)
143 at org.jvnet.mjiip.v_2_3.XJC23Mojo.doExecute(XJC23Mojo.java:28)
144 at org.jvnet.jaxb2.maven2.RawXJC2Mojo.doExecute(RawXJC2Mojo.java:478)
145 at org.jvnet.jaxb2.maven2.RawXJC2Mojo.execute(RawXJC2Mojo.java:320)
146 at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
147 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
148 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
149 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
150 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
151 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
152 at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
153 at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
154 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
155 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
156 at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
157 at org.apache.maven.cli.MavenCli.execute(MavenCli.java:957)
158 at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289)
159 at org.apache.maven.cli.MavenCli.main(MavenCli.java:193)
160 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
161 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
162 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
163 at java.base/java.lang.reflect.Method.invoke(Method.java:568)
164 at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
165 at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
166 at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
167 at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
168 at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
169Caused by: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
170 at java.base/java.lang.Class.getMethod(Class.java:2227)
171 at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:201)
172 at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:197)
173 at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
174 ... 109 more
175 <build>
176 <plugins>
177 <plugin>
178 <groupId>org.jvnet.jaxb2.maven2</groupId>
179 <artifactId>maven-jaxb2-plugin</artifactId>
180 <version>0.14.0</version>
181 <dependencies>
182 <dependency>
183 <groupId>org.glassfish.jaxb</groupId>
184 <artifactId>jaxb-runtime</artifactId>
185 <version>${jaxb-api.version}</version>
186 </dependency>
187
Notice, that I didn't close all open tags, because those are irrelevant to the question. Those are just open for clarity of where to put jaxb-runtime dependency. I used 2.3.1 version, and it compiled.
QUESTION
Make a Java class visible from any ClassLoader
Asked 2021-Dec-13 at 17:17I'm using a Java Agent (Agent.class) to transform a method in a program (Program.class) in a way that includes a call to the Agent class.
1public Program.getMultiplier()F:
2 ALOAD 1
3 ALOAD 2
4 FDIV
5+ INVOKESTATIC Agent.getCustomMultiplier(F)F
6 FRETURN
7
I've inspected the class loaders and their parents of both Agent and Program classes, and their hierarchy looks like this:
- Agent.class:
AppClassLoader
<-PlatformClassLoader
<-null
- Program.class:
URLClassLoader
<-PlatformClassLoader
<-null
When the Program executes the added INVOKESTATIC
instruction, it throws a ClassNotFoundException -- it cannot find the Agent class as it was loaded by a different class loader.
As a temporary solution, I've tried forcing AppClassLoader
to become a parent of URLClassLoader
with reflection, which works in older Java versions but has been removed since Java 12.
Is there a more reliable way to make sure my Agent class is visible from any class loader?
ANSWER
Answered 2021-Dec-13 at 14:20Have your Agent listen to the creation of new ClassLoaders and then attach instances of them to the new ClassLoaders.
This way you preserve your "Agent listens to ClassLoader" interface, even if it now extends beyond the one platform class loader you expected the Agent to listen to.
QUESTION
R2dbc Repositories always null with Mockito
Asked 2021-Dec-07 at 10:10I am trying to test a service but the Repository is always null. When using a JPA repository I never had this issue. I am not sure if it has something to do with ReactiveCrudRepository. Has anyone encountered this issue?
1 @RunWith(MockitoJUnitRunner.class)
2 class UserTest {
3
4
5 @InjectMocks
6 private UserService underTest;
7
8 @Mock
9 private UserRepository userRepository;
10
11 @Mock
12 private AutoCloseable closeable;
13
14 @BeforeEach
15 public void init() {
16 closeable = MockitoAnnotations.openMocks(this);
17 }
18
19 @AfterEach
20 public void closeService() throws Exception {
21 closeable.close();
22 }
23
24 @Test
25 void getApplicableUsers() {
26
27
28 when(userRepository.findAll().collectList().block()).thenReturn(new ArrayList<>());
29 Set<User> expected = underTest.getUsers(getUser(), getUsers());
30
31 verify(underTest, times(1)).updateUsers(getUser(),expected);
32
33 }
34
35 }
36
1 @RunWith(MockitoJUnitRunner.class)
2 class UserTest {
3
4
5 @InjectMocks
6 private UserService underTest;
7
8 @Mock
9 private UserRepository userRepository;
10
11 @Mock
12 private AutoCloseable closeable;
13
14 @BeforeEach
15 public void init() {
16 closeable = MockitoAnnotations.openMocks(this);
17 }
18
19 @AfterEach
20 public void closeService() throws Exception {
21 closeable.close();
22 }
23
24 @Test
25 void getApplicableUsers() {
26
27
28 when(userRepository.findAll().collectList().block()).thenReturn(new ArrayList<>());
29 Set<User> expected = underTest.getUsers(getUser(), getUsers());
30
31 verify(underTest, times(1)).updateUsers(getUser(),expected);
32
33 }
34
35 }
36> error
37>
38> java.lang.NullPointerException
39> at com.user.UserServiceTest.updateUsers(UserService.java:99)
40> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
41> Method)
42> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
43> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
44> at java.base/java.lang.reflect.Method.invoke(Method.java:566)
45> at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
46> at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
47> at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
48> at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
49> at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
50> at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
51> at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
52> at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
53> at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
54> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
55> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
56> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
57> at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
58> at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
59> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
60> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
61> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
62> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
63> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
64> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
65> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
66> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
67> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
68> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
69> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
70> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
71> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
72> at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
73> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
74> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
75> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
76> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
77> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
78> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
79> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
80> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
81> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
82> at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
83> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
84> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
85> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
86> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
87> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
88> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
89> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
90> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
91> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
92> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
93> at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
94> at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
95> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
96> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
97> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
98> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
99> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
100> at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
101> at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
102> at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
103> at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
104> at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
105> at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
106> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
107> Method)
108> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
109> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
110> at java.base/java.lang.reflect.Method.invoke(Method.java:566)
111> at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
112> at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
113> at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
114> at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
115> at com.sun.proxy.$Proxy5.stop(Unknown Source)
116> at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:135)
117> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
118> Method)
119> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
120> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
121> at java.base/java.lang.reflect.Method.invoke(Method.java:566)
122> at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
123> at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
124> at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
125> at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
126> at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
127> at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
128> at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
129> at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
130> at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
131> at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
132> at java.base/java.lang.Thread.run(Thread.java:829)
133
------------- update 1 -------
I figured out what the issue was but not the solution. If I use .block it is always null however in this case I need to use block. Has anyone been able to use block or optionalBlock() and been able to mock it?
ANSWER
Answered 2021-Dec-04 at 09:38findAll()
method is not mocked, thus a null value is returned. You should mock userRepository.findAll()
instead of userRepository.findAll().collectList().block()
.
Try this:
1 @RunWith(MockitoJUnitRunner.class)
2 class UserTest {
3
4
5 @InjectMocks
6 private UserService underTest;
7
8 @Mock
9 private UserRepository userRepository;
10
11 @Mock
12 private AutoCloseable closeable;
13
14 @BeforeEach
15 public void init() {
16 closeable = MockitoAnnotations.openMocks(this);
17 }
18
19 @AfterEach
20 public void closeService() throws Exception {
21 closeable.close();
22 }
23
24 @Test
25 void getApplicableUsers() {
26
27
28 when(userRepository.findAll().collectList().block()).thenReturn(new ArrayList<>());
29 Set<User> expected = underTest.getUsers(getUser(), getUsers());
30
31 verify(underTest, times(1)).updateUsers(getUser(),expected);
32
33 }
34
35 }
36> error
37>
38> java.lang.NullPointerException
39> at com.user.UserServiceTest.updateUsers(UserService.java:99)
40> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
41> Method)
42> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
43> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
44> at java.base/java.lang.reflect.Method.invoke(Method.java:566)
45> at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
46> at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
47> at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
48> at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
49> at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
50> at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
51> at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
52> at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
53> at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
54> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
55> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
56> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
57> at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
58> at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
59> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
60> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
61> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
62> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
63> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
64> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
65> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
66> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
67> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
68> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
69> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
70> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
71> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
72> at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
73> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
74> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
75> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
76> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
77> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
78> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
79> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
80> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
81> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
82> at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
83> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
84> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
85> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
86> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
87> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
88> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
89> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
90> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
91> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
92> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
93> at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
94> at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
95> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
96> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
97> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
98> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
99> at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
100> at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
101> at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
102> at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
103> at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
104> at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
105> at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
106> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
107> Method)
108> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
109> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
110> at java.base/java.lang.reflect.Method.invoke(Method.java:566)
111> at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
112> at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
113> at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
114> at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
115> at com.sun.proxy.$Proxy5.stop(Unknown Source)
116> at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:135)
117> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
118> Method)
119> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
120> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
121> at java.base/java.lang.reflect.Method.invoke(Method.java:566)
122> at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
123> at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
124> at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
125> at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
126> at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
127> at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
128> at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
129> at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
130> at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
131> at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
132> at java.base/java.lang.Thread.run(Thread.java:829)
133when(userRepository.findAll()).thenReturn(Flux.empty());
134
QUESTION
Filling missing values with mean in pyspark
Asked 2021-Nov-15 at 09:17I am trying to fill NaN values with mean using pyspark. Below is my code that I am using and following is the error that occurred-
1from pyspark.sql.functions import avg
2
3
4def fill_with_mean(df_1, exclude=set()):
5 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
6 return df_1.na.fill(stats.first().asDict())
7
8res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
9res.show()
10
Error-
1from pyspark.sql.functions import avg
2
3
4def fill_with_mean(df_1, exclude=set()):
5 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
6 return df_1.na.fill(stats.first().asDict())
7
8res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
9res.show()
10Py4JJavaError Traceback (most recent call last)
11 <ipython-input-35-42f4d984f022> in <module>()
12 3 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
13 4 return df_1.na.fill(stats.first().asDict())
14 ----> 5 res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
15 6 res.show()
16
17
18
19 5 frames
20 /usr/local/lib/python3.7/dist-packages/py4j/protocol.py in get_return_value(answer,
21 gateway_client, target_id, name)
22 326 raise Py4JJavaError(
23 327 "An error occurred while calling {0}{1}{2}.\n".
24 --> 328 format(target_id, ".", name), value)
25 329 else:
26 330 raise Py4JError(
27
28 Py4JJavaError: An error occurred while calling o376.fill.
29 : java.lang.NullPointerException
30at org.apache.spark.sql.DataFrameNaFunctions.$anonfun$fillMap$1(DataFrameNaFunctions.scala:418)
31at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:286)
32at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
33at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
34at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
35at scala.collection.TraversableLike.map(TraversableLike.scala:286)
36at scala.collection.TraversableLike.map$(TraversableLike.scala:279)
37at scala.collection.AbstractTraversable.map(Traversable.scala:108)
38at org.apache.spark.sql.DataFrameNaFunctions.fillMap(DataFrameNaFunctions.scala:407)
39at org.apache.spark.sql.DataFrameNaFunctions.fill(DataFrameNaFunctions.scala:232)
40at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
41at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
42at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
43at java.base/java.lang.reflect.Method.invoke(Method.java:566)
44at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
45at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
46at py4j.Gateway.invoke(Gateway.java:282)
47
Can you let me know where am I going wrong? Is there any alternative way to fill missing values using mean?
This is how my dataframe looks like:-
I wish to see mean values filled in place of null. Also, Evaporation and sunshine are not completely null, there are other values in it too.
The dataset is a csv file-
1from pyspark.sql.functions import avg
2
3
4def fill_with_mean(df_1, exclude=set()):
5 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
6 return df_1.na.fill(stats.first().asDict())
7
8res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
9res.show()
10Py4JJavaError Traceback (most recent call last)
11 <ipython-input-35-42f4d984f022> in <module>()
12 3 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
13 4 return df_1.na.fill(stats.first().asDict())
14 ----> 5 res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
15 6 res.show()
16
17
18
19 5 frames
20 /usr/local/lib/python3.7/dist-packages/py4j/protocol.py in get_return_value(answer,
21 gateway_client, target_id, name)
22 326 raise Py4JJavaError(
23 327 "An error occurred while calling {0}{1}{2}.\n".
24 --> 328 format(target_id, ".", name), value)
25 329 else:
26 330 raise Py4JError(
27
28 Py4JJavaError: An error occurred while calling o376.fill.
29 : java.lang.NullPointerException
30at org.apache.spark.sql.DataFrameNaFunctions.$anonfun$fillMap$1(DataFrameNaFunctions.scala:418)
31at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:286)
32at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
33at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
34at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
35at scala.collection.TraversableLike.map(TraversableLike.scala:286)
36at scala.collection.TraversableLike.map$(TraversableLike.scala:279)
37at scala.collection.AbstractTraversable.map(Traversable.scala:108)
38at org.apache.spark.sql.DataFrameNaFunctions.fillMap(DataFrameNaFunctions.scala:407)
39at org.apache.spark.sql.DataFrameNaFunctions.fill(DataFrameNaFunctions.scala:232)
40at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
41at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
42at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
43at java.base/java.lang.reflect.Method.invoke(Method.java:566)
44at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
45at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
46at py4j.Gateway.invoke(Gateway.java:282)
47from pyspark.sql.functions import *
48import pyspark
49infer_schema = "true"
50first_row_is_header = "true"
51delimiter = ","
52df_1= spark.read.format("csv").option("header","true").load('/content/weatherAUS.csv')
53df_1.show()
54
ANSWER
Answered 2021-Nov-15 at 09:17Based on your input data, I create my dataframe :
1from pyspark.sql.functions import avg
2
3
4def fill_with_mean(df_1, exclude=set()):
5 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
6 return df_1.na.fill(stats.first().asDict())
7
8res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
9res.show()
10Py4JJavaError Traceback (most recent call last)
11 <ipython-input-35-42f4d984f022> in <module>()
12 3 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
13 4 return df_1.na.fill(stats.first().asDict())
14 ----> 5 res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
15 6 res.show()
16
17
18
19 5 frames
20 /usr/local/lib/python3.7/dist-packages/py4j/protocol.py in get_return_value(answer,
21 gateway_client, target_id, name)
22 326 raise Py4JJavaError(
23 327 "An error occurred while calling {0}{1}{2}.\n".
24 --> 328 format(target_id, ".", name), value)
25 329 else:
26 330 raise Py4JError(
27
28 Py4JJavaError: An error occurred while calling o376.fill.
29 : java.lang.NullPointerException
30at org.apache.spark.sql.DataFrameNaFunctions.$anonfun$fillMap$1(DataFrameNaFunctions.scala:418)
31at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:286)
32at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
33at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
34at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
35at scala.collection.TraversableLike.map(TraversableLike.scala:286)
36at scala.collection.TraversableLike.map$(TraversableLike.scala:279)
37at scala.collection.AbstractTraversable.map(Traversable.scala:108)
38at org.apache.spark.sql.DataFrameNaFunctions.fillMap(DataFrameNaFunctions.scala:407)
39at org.apache.spark.sql.DataFrameNaFunctions.fill(DataFrameNaFunctions.scala:232)
40at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
41at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
42at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
43at java.base/java.lang.reflect.Method.invoke(Method.java:566)
44at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
45at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
46at py4j.Gateway.invoke(Gateway.java:282)
47from pyspark.sql.functions import *
48import pyspark
49infer_schema = "true"
50first_row_is_header = "true"
51delimiter = ","
52df_1= spark.read.format("csv").option("header","true").load('/content/weatherAUS.csv')
53df_1.show()
54from pyspark.sql import functions as F, Window
55
56df = spark.read.csv("./weatherAUS.csv", header=True, inferSchema=True, nullValue="NA")
57
Then, I process the whole dataframe, excluding the columns you mentionned + the columns that cannot be replaced (date and location)
1from pyspark.sql.functions import avg
2
3
4def fill_with_mean(df_1, exclude=set()):
5 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
6 return df_1.na.fill(stats.first().asDict())
7
8res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
9res.show()
10Py4JJavaError Traceback (most recent call last)
11 <ipython-input-35-42f4d984f022> in <module>()
12 3 stats = df_1.agg(*(avg(c).alias(c) for c in df_1.columns if c not in exclude))
13 4 return df_1.na.fill(stats.first().asDict())
14 ----> 5 res = fill_with_mean(df_1, ["MinTemp", "MaxTemp", "Evaporation", "Sunshine"])
15 6 res.show()
16
17
18
19 5 frames
20 /usr/local/lib/python3.7/dist-packages/py4j/protocol.py in get_return_value(answer,
21 gateway_client, target_id, name)
22 326 raise Py4JJavaError(
23 327 "An error occurred while calling {0}{1}{2}.\n".
24 --> 328 format(target_id, ".", name), value)
25 329 else:
26 330 raise Py4JError(
27
28 Py4JJavaError: An error occurred while calling o376.fill.
29 : java.lang.NullPointerException
30at org.apache.spark.sql.DataFrameNaFunctions.$anonfun$fillMap$1(DataFrameNaFunctions.scala:418)
31at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:286)
32at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
33at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
34at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
35at scala.collection.TraversableLike.map(TraversableLike.scala:286)
36at scala.collection.TraversableLike.map$(TraversableLike.scala:279)
37at scala.collection.AbstractTraversable.map(Traversable.scala:108)
38at org.apache.spark.sql.DataFrameNaFunctions.fillMap(DataFrameNaFunctions.scala:407)
39at org.apache.spark.sql.DataFrameNaFunctions.fill(DataFrameNaFunctions.scala:232)
40at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
41at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
42at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
43at java.base/java.lang.reflect.Method.invoke(Method.java:566)
44at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
45at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
46at py4j.Gateway.invoke(Gateway.java:282)
47from pyspark.sql.functions import *
48import pyspark
49infer_schema = "true"
50first_row_is_header = "true"
51delimiter = ","
52df_1= spark.read.format("csv").option("header","true").load('/content/weatherAUS.csv')
53df_1.show()
54from pyspark.sql import functions as F, Window
55
56df = spark.read.csv("./weatherAUS.csv", header=True, inferSchema=True, nullValue="NA")
57exclude = ["date", "location"] + ["mintemp", "maxtemp", "evaporation", "sunshine"]
58
59
60df2 = df.select(
61 *(
62 F.coalesce(F.col(col), F.avg(col).over(Window.orderBy(F.lit(1)))).alias(col)
63 if col.lower() not in exclude
64 else F.col(col)
65 for col in df.columns
66 )
67)
68
69df2.show(5)
70+-------------------+----------+-------+-------+--------+-----------+--------+-----------+-------------+----------+----------+------------+------------+-----------+-----------+-----------+-----------+--------+--------+-------+-------+---------+------------+
71| Date| Location|MinTemp|MaxTemp|Rainfall|Evaporation|Sunshine|WindGustDir|WindGustSpeed|WindDir9am|WindDir3pm|WindSpeed9am|WindSpeed3pm|Humidity9am|Humidity3pm|Pressure9am|Pressure3pm|Cloud9am|Cloud3pm|Temp9am|Temp3pm|RainToday|RainTomorrow|
72+-------------------+----------+-------+-------+--------+-----------+--------+-----------+-------------+----------+----------+------------+------------+-----------+-----------+-----------+-----------+--------+--------+-------+-------+---------+------------+
73|2012-07-02 22:00:00|Townsville| 12.4| 23.3| 0.0| 6.0| 10.8| SSW| 33.0| SE| S| 7.0| 20.0| 34.0| 28.0| 1019.5| 1015.5| 1.0| 2.0| 17.5| 23.0| No| No|
74|2012-07-03 22:00:00|Townsville| 9.1| 21.7| 0.0| 5.0| 10.9| SE| 39.0| SSW| SSE| 17.0| 20.0| 26.0| 14.0| 1021.7| 1018.4| 1.0| 0.0| 16.4| 21.2| No| No|
75|2012-07-04 22:00:00|Townsville| 8.2| 23.4| 0.0| 5.2| 10.6| SSW| 30.0| SSW| NE| 22.0| 13.0| 34.0| 40.0| 1021.7| 1018.5| 2.0| 2.0| 17.1| 22.3| No| No|
76|2012-07-05 22:00:00|Townsville| 10.5| 24.5| 0.0| 6.0| 10.2| E| 39.0| SSW| SE| 11.0| 17.0| 48.0| 31.0| 1021.2| 1017.2| 1.0| 2.0| 17.9| 23.8| No| No|
77|2012-07-06 22:00:00|Townsville| 17.7| 24.1| 0.0| 6.8| 0.5| SE| 54.0| SE| ESE| 19.0| 31.0| 69.0| 58.0| 1019.2| 1017.0| 8.0| 7.0| 20.1| 23.2| No| No|
78+-------------------+----------+-------+-------+--------+-----------+--------+-----------+-------------+----------+----------+------------+------------+-----------+-----------+-----------+-----------+--------+--------+-------+-------+---------+------------+
79only showing top 5 rows
80
Community Discussions contain sources that include Stack Exchange Network
Tutorials and Learning Resources in Reflection
Tutorials and Learning Resources are not available at this moment for Reflection