Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
SquirrelJME
Commits
37688f5c
Commit
37688f5c
authored
Jul 18, 2021
by
Stephanie Gawroriski
Browse files
Merge in the Gradle updates.
parents
d960cdce
ea91e780
Pipeline
#39172
passed with stages
in 1 minute and 32 seconds
Changes
32
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
.fossil-settings/ignore-glob
View file @
37688f5c
...
...
@@ -22,6 +22,12 @@ out/
ratufacoat/.idea/workspace.xml
file-*
# IntelliJ Dependency Matrix
emulators/*/out/production/
emulators/*/out/test/
modules/*/out/production/
modules/*/out/test/
# Contributions
*.diff
*.gdiff
...
...
.gitignore
View file @
37688f5c
...
...
@@ -22,6 +22,12 @@ out/
ratufacoat/.idea/workspace.xml
file-*
# IntelliJ Dependency Matrix
emulators/*/out/production/
emulators/*/out/test/
modules/*/out/production/
modules/*/out/test/
# Contributions
*.diff
*.gdiff
...
...
@@ -61,7 +67,26 @@ ratufacoat/out
# Fossil files
_FOSSIL_
ci-comment-*.txt
ci-comment-*.txtout-*1*
out-*2*
out-*3*
out-*4*
out-*5*
out-*6*
out-*7*
out-*8*
out-*9*
out-*0*
in-*1*
in-*2*
in-*3*
in-*4*
in-*5*
in-*6*
in-*7*
in-*8*
in-*9*
in-*0*
in-*0
in-*1
in-*2
...
...
.idea/copyright/profiles_settings.xml
View file @
37688f5c
<component
name=
"CopyrightManager"
>
<settings>
<settings
default=
"DefaultCopyright"
>
<LanguageOptions
name=
"JAVA"
>
<option
name=
"fileTypeOverride"
value=
"3"
/>
<option
name=
"block"
value=
"false"
/>
...
...
@@ -8,4 +8,4 @@
<option
name=
"block"
value=
"false"
/>
</LanguageOptions>
</settings>
</component>
\ No newline at end of file
</component>
.idea/inspectionProfiles/Project_Default.xml
View file @
37688f5c
...
...
@@ -18,7 +18,9 @@
<inspection_tool
class=
"ArraysAsListWithZeroOrOneArgument"
enabled=
"false"
level=
"WARNING"
enabled_by_default=
"false"
/>
<inspection_tool
class=
"AssertEqualsBetweenInconvertibleTypes"
enabled=
"false"
level=
"WARNING"
enabled_by_default=
"false"
/>
<inspection_tool
class=
"AssignmentUsedAsCondition"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
/>
<inspection_tool
class=
"AutoCloseableResource"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
/>
<inspection_tool
class=
"AutoCloseableResource"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
>
<option
name=
"METHOD_MATCHER_CONFIG"
value=
"java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,net.multiphasicapps.io.ChunkWriter,addSection"
/>
</inspection_tool>
<inspection_tool
class=
"BeforeClassOrAfterClassIsPublicStaticVoidNoArg"
enabled=
"false"
level=
"WARNING"
enabled_by_default=
"false"
/>
<inspection_tool
class=
"BeforeOrAfterIsPublicVoidNoArg"
enabled=
"false"
level=
"WARNING"
enabled_by_default=
"false"
/>
<inspection_tool
class=
"BooleanMethodNameMustStartWithQuestion"
enabled=
"false"
level=
"WEAK WARNING"
enabled_by_default=
"false"
>
...
...
@@ -344,7 +346,7 @@
<inspection_tool
class=
"UnnecessaryConstructor"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
/>
<inspection_tool
class=
"UnnecessaryFinalOnLocalVariableOrParameter"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
/>
<inspection_tool
class=
"UnnecessarySuperConstructor"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
/>
<inspection_tool
class=
"Unnecessary
SuperQualifier
"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
/>
<inspection_tool
class=
"Unnecessary
ToStringCall
"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
/>
<inspection_tool
class=
"UnqualifiedFieldAccess"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
/>
<inspection_tool
class=
"UnqualifiedInnerClassAccess"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
>
<option
name=
"ignoreReferencesToLocalInnerClasses"
value=
"true"
/>
...
...
@@ -377,4 +379,4 @@
<option
name=
"ADD_NONJAVA_TO_ENTRIES"
value=
"true"
/>
</inspection_tool>
</profile>
</component>
\ No newline at end of file
</component>
buildSrc/src/main/java/cc/squirreljme/plugin/SquirrelJMEPluginConfiguration.java
View file @
37688f5c
...
...
@@ -16,8 +16,10 @@ import cc.squirreljme.plugin.swm.JavaMEMidletType;
import
cc.squirreljme.plugin.swm.JavaMEProfile
;
import
cc.squirreljme.plugin.swm.JavaMEStandard
;
import
java.util.ArrayList
;
import
java.util.LinkedHashMap
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
org.gradle.api.Project
;
import
org.gradle.api.UnknownDomainObjectException
;
...
...
@@ -77,6 +79,13 @@ public class SquirrelJMEPluginConfiguration
/** Is this a bootloader? */
public
boolean
isBootLoader
;
/** System properties to be used by tests only. */
public
Map
<
String
,
String
>
testSystemProperties
=
new
LinkedHashMap
<>();
/** Do not run these tests in parallel. */
public
boolean
noParallelTests
;
/**
* Initializes the configuration with the contained project.
*
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/general/ListErrorPrefixTask.java
View file @
37688f5c
...
...
@@ -9,10 +9,8 @@
package
cc.squirreljme.plugin.general
;
import
cc.squirreljme.plugin.ErrorCodeManager
;
import
javax.inject.Inject
;
import
org.gradle.api.DefaultTask
;
import
org.gradle.api.Task
;
/**
* Lists error prefixes for the task.
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/AlwaysTrue.java
View file @
37688f5c
...
...
@@ -9,7 +9,6 @@
package
cc.squirreljme.plugin.multivm
;
import
groovy.lang.Closure
;
import
org.gradle.api.Task
;
import
org.gradle.api.specs.Spec
;
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/DefunctTestTask.java
View file @
37688f5c
...
...
@@ -11,7 +11,6 @@ package cc.squirreljme.plugin.multivm;
import
javax.inject.Inject
;
import
org.gradle.api.Task
;
import
org.gradle.api.tasks.TaskExecutionException
;
import
org.gradle.api.tasks.testing.Test
;
/**
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/TaskInitialization.java
View file @
37688f5c
...
...
@@ -119,6 +119,12 @@ public final class TaskInitialization
TaskInitialization
.
task
(
"lib"
,
__sourceSet
,
__vmType
),
VMLibraryTask
.
class
,
__sourceSet
,
__vmType
);
// Is dumping available?
if
(
__vmType
.
hasDumping
())
tasks
.
create
(
TaskInitialization
.
task
(
"dump"
,
__sourceSet
,
__vmType
),
VMDumpLibraryTask
.
class
,
__sourceSet
,
__vmType
,
libTask
);
// Running the target
if
(
__sourceSet
.
equals
(
SourceSet
.
MAIN_SOURCE_SET_NAME
))
tasks
.
create
(
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMDumpLibraryTask.java
0 → 100644
View file @
37688f5c
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
// Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------
package
cc.squirreljme.plugin.multivm
;
import
java.io.File
;
import
java.nio.file.Paths
;
import
javax.inject.Inject
;
import
org.gradle.api.DefaultTask
;
import
org.gradle.api.Project
;
import
org.gradle.api.provider.Provider
;
import
org.gradle.jvm.tasks.Jar
;
/**
* This is used to dump the output compilation result of a library.
*
* @since 2021/05/16
*/
public
class
VMDumpLibraryTask
extends
DefaultTask
implements
VMExecutableTask
{
/** The source set used. */
public
final
String
sourceSet
;
/** The virtual machine type. */
public
final
VMSpecifier
vmType
;
/**
* Initializes the library dumping task.
*
* @param __sourceSet The source set used.
* @param __vmType The virtual machine type.
* @throws NullPointerException On null arguments.
* @since 2021/05/16
*/
@Inject
public
VMDumpLibraryTask
(
String
__sourceSet
,
VMSpecifier
__vmType
,
VMLibraryTask
__libTask
)
throws
NullPointerException
{
if
(
__sourceSet
==
null
||
__vmType
==
null
)
throw
new
NullPointerException
(
"NARG"
);
Project
project
=
this
.
getProject
();
Jar
baseJar
=
VMHelpers
.
jarTask
(
project
,
__sourceSet
);
// These are used at the build stage
this
.
sourceSet
=
__sourceSet
;
this
.
vmType
=
__vmType
;
// Set details of this task
this
.
setGroup
(
"squirreljme"
);
this
.
setDescription
(
"Dumps the compiled library for debugging."
);
// We need to build the library before we can dump it
this
.
dependsOn
(
baseJar
,
__libTask
);
// The input is the output of the library task, which is a glob
Provider
<
File
>
file
=
this
.
getProject
().
provider
(
()
->
__libTask
.
getOutputs
().
getFiles
().
getSingleFile
());
this
.
getInputs
().
file
(
file
);
// The output depends on the task and its source set
this
.
getOutputs
().
file
(
this
.
getProject
().
provider
(
()
->
Paths
.
get
(
file
.
get
()
+
".yml"
).
toFile
()));
this
.
getOutputs
().
upToDateWhen
(
new
VMLibraryTaskUpToDate
(
this
.
vmType
));
// Performs the action of the task
this
.
doLast
(
new
VMDumpLibraryTaskAction
(
__sourceSet
,
__vmType
));
}
/**
* {@inheritDoc}
* @since 2021/05/16
*/
@Override
public
String
getSourceSet
()
{
return
this
.
sourceSet
;
}
}
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMDumpLibraryTaskAction.java
0 → 100644
View file @
37688f5c
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
// Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------
package
cc.squirreljme.plugin.multivm
;
import
org.gradle.api.Action
;
import
org.gradle.api.Task
;
/**
* This performs the action of dumping a compiled library glob.
*
* @since 2021/05/16
*/
public
class
VMDumpLibraryTaskAction
implements
Action
<
Task
>
{
/** The source set used. */
public
final
String
sourceSet
;
/** The virtual machine type. */
public
final
VMSpecifier
vmType
;
/**
* Initializes the task action.
*
* @param __sourceSet The source set.
* @param __vmType The virtual machine type.
* @throws NullPointerException On null arguments.
* @since 2021/05/16
*/
public
VMDumpLibraryTaskAction
(
String
__sourceSet
,
VMSpecifier
__vmType
)
throws
NullPointerException
{
if
(
__sourceSet
==
null
||
__vmType
==
null
)
throw
new
NullPointerException
(
"NARG"
);
this
.
sourceSet
=
__sourceSet
;
this
.
vmType
=
__vmType
;
}
/**
* {@inheritDoc}
* @since 2021/05/16
*/
@Override
public
void
execute
(
Task
__task
)
{
VMLibraryTaskAction
.
execute
(
__task
,
this
.
vmType
,
this
.
sourceSet
,
this
.
vmType
::
dumpLibrary
);
}
}
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMEmulatorDependencies.java
View file @
37688f5c
...
...
@@ -9,10 +9,17 @@
package
cc.squirreljme.plugin.multivm
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedList
;
import
java.util.Set
;
import
java.util.concurrent.Callable
;
import
org.gradle.api.Project
;
import
org.gradle.api.Task
;
import
org.gradle.api.tasks.SourceSet
;
import
org.gradle.api.tasks.TaskContainer
;
/**
* This class is used to provide the dependency lookup for the emulator
...
...
@@ -58,10 +65,32 @@ public final class VMEmulatorDependencies
{
Project
root
=
this
.
task
.
getProject
().
getRootProject
();
return
Arrays
.<
Task
>
asList
(
root
.
project
(
this
.
vmType
.
emulatorProject
())
.
getTasks
().
getByName
(
"assemble"
),
root
.
project
(
":emulators:emulator-base"
)
.
getTasks
().
getByName
(
"jar"
));
Project
emuProject
=
root
.
project
(
this
.
vmType
.
emulatorProject
());
TaskContainer
emuTasks
=
emuProject
.
getTasks
();
TaskContainer
emuBase
=
root
.
project
(
":emulators:emulator-base"
)
.
getTasks
();
// Build projects that are needed to run the emulator
Set
<
Task
>
rv
=
new
LinkedHashSet
<>();
for
(
ProjectAndTaskName
task
:
VMHelpers
.
runClassTasks
(
emuProject
,
SourceSet
.
MAIN_SOURCE_SET_NAME
,
VMType
.
HOSTED
))
{
Project
taskProject
=
root
.
project
(
task
.
project
);
// We need to depend on the classes and JAR for the emulator
// projects
rv
.
add
(
taskProject
.
getTasks
().
getByName
(
"classes"
));
rv
.
add
(
taskProject
.
getTasks
().
getByName
(
"jar"
));
}
// Add base emulator projects and such, so that they are forced
rv
.
add
(
emuTasks
.
getByName
(
"jar"
));
rv
.
add
(
emuTasks
.
getByName
(
"assemble"
));
rv
.
add
(
emuBase
.
getByName
(
"jar"
));
rv
.
add
(
emuBase
.
getByName
(
"assemble"
));
rv
.
add
(
emuBase
.
getByName
(
"assembleDebug"
));
rv
.
add
(
emuBase
.
getByName
(
"assembleRelease"
));
return
new
ArrayList
<>(
rv
);
}
}
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMFullSuiteTaskAction.java
View file @
37688f5c
...
...
@@ -118,7 +118,7 @@ public class VMFullSuiteTaskAction
ExecResult
exitResult
=
__task
.
getProject
().
javaexec
(
__spec
->
{
// Use filled JVM arguments
this
.
vmType
.
spawnJvmArguments
(
__task
,
this
.
vmType
.
spawnJvmArguments
(
__task
,
false
,
new
GradleJavaExecSpecFiller
(
__spec
),
"javax.microedition.midlet.__MainHandler__"
,
new
LinkedHashMap
<
String
,
String
>(),
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMHelpers.java
View file @
37688f5c
...
...
@@ -802,7 +802,7 @@ public final class VMHelpers
return
Collections
.
unmodifiableMap
(
singles
);
// If the test has no matching file, then just ignore it
__project
.
getLogger
().
info
(
"Could not find test {}, ignoring."
,
__project
.
getLogger
().
warn
(
"Could not find test {}, ignoring."
,
singleTest
);
}
...
...
@@ -930,13 +930,19 @@ public final class VMHelpers
// If the test does not have a multi-parameter match it exactly.
// However if we requested a specific multi-parameter then match that
// as well
// as well.
// Convert slashes to dots as well for binary name usage
int
la
=
__key
.
indexOf
(
'@'
);
if
(
la
<
0
||
__singleTest
.
indexOf
(
'@'
)
>=
0
)
return
__key
.
equals
(
__singleTest
);
return
__key
.
equals
(
__singleTest
)
||
__key
.
equals
(
__singleTest
.
replace
(
'/'
,
'.'
));
// Only match by the basename, if multi-parameter assume all of them
return
__key
.
substring
(
0
,
la
).
equals
(
__singleTest
);
// But also convert all slashes to dots in the event binary names
// are used.
return
__key
.
substring
(
0
,
la
).
equals
(
__singleTest
)
||
__key
.
substring
(
0
,
la
).
equals
(
__singleTest
.
replace
(
'/'
,
'.'
));
}
/**
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMLibraryExecuteFunction.java
0 → 100644
View file @
37688f5c
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
// Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------
package
cc.squirreljme.plugin.multivm
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
org.gradle.api.Task
;
/**
* Not Described.
*
* @since 2021/05/16
*/
@FunctionalInterface
public
interface
VMLibraryExecuteFunction
{
/**
* Performs the function as required.
*
* @param __task The task used.
* @param __isTest Is this a test?
* @param __in The input stream.
* @param __out The output stream.
* @throws IOException Any read/write errors.
* @since 2021/05/16
*/
void
function
(
Task
__task
,
boolean
__isTest
,
InputStream
__in
,
OutputStream
__out
)
throws
IOException
;
}
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMLibraryTask.java
View file @
37688f5c
...
...
@@ -68,6 +68,8 @@ public class VMLibraryTask
// The output depends on the task and its source set
this
.
getOutputs
().
file
(
this
.
outputPath
());
this
.
getOutputs
().
upToDateWhen
(
new
VMLibraryTaskUpToDate
(
this
.
vmType
));
// Performs the action of the task
this
.
doLast
(
new
VMLibraryTaskAction
(
__sourceSet
,
__vmType
));
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMLibraryTaskAction.java
View file @
37688f5c
...
...
@@ -16,6 +16,7 @@ import java.nio.file.Files;
import
java.nio.file.Path
;
import
java.nio.file.StandardCopyOption
;
import
java.nio.file.StandardOpenOption
;
import
java.util.function.Function
;
import
org.gradle.api.Action
;
import
org.gradle.api.Task
;
import
org.gradle.api.tasks.SourceSet
;
...
...
@@ -59,6 +60,22 @@ public class VMLibraryTaskAction
*/
@Override
public
void
execute
(
Task
__task
)
{
VMLibraryTaskAction
.
execute
(
__task
,
this
.
vmType
,
this
.
sourceSet
,
this
.
vmType
::
processLibrary
);
}
/**
* Performs a library like action.
*
* @param __task The task calling from.
* @param __vmType The virtual machine type.
* @param __sourceSet The source set used.
* @param __func The function to use.
* @since 2021/05/16
*/
public
static
void
execute
(
Task
__task
,
VMSpecifier
__vmType
,
String
__sourceSet
,
VMLibraryExecuteFunction
__func
)
{
// Open the input library for processing
Path
tempFile
=
null
;
...
...
@@ -67,15 +84,15 @@ public class VMLibraryTaskAction
{
// Where shall this go?
tempFile
=
Files
.
createTempFile
(
this
.
vmType
.
vmName
(
VMNameFormat
.
LOWERCASE
),
this
.
sourceSet
);
__
vmType
.
vmName
(
VMNameFormat
.
LOWERCASE
),
__
sourceSet
);
// Setup output file for writing
try
(
OutputStream
out
=
Files
.
newOutputStream
(
tempFile
,
StandardOpenOption
.
WRITE
,
StandardOpenOption
.
TRUNCATE_EXISTING
,
StandardOpenOption
.
CREATE
))
{
this
.
vmType
.
processLibrary
(
__task
,
SourceSet
.
TEST_SOURCE_SET_NAME
.
equals
(
this
.
sourceSet
),
__func
.
function
(
__task
,
SourceSet
.
TEST_SOURCE_SET_NAME
.
equals
(
__
sourceSet
),
in
,
out
);
}
...
...
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMLibraryTaskUpToDate.java
0 → 100644
View file @
37688f5c
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
// Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------
package
cc.squirreljme.plugin.multivm
;
import
java.io.File
;
import
java.time.Instant
;
import
java.util.HashSet
;
import
java.util.Set
;
import
org.gradle.api.Task
;
import
org.gradle.api.specs.Spec
;
/**
* This is a check to determine if a task is up to date or not for the library
* compiler.
*
* @since 2020/11/28
*/
public
class
VMLibraryTaskUpToDate
implements
Spec
<
Task
>
{
/** The virtual machine to target. */
protected
final
VMSpecifier
vmType
;
/**
* Initializes the task dependencies.
*
* @param __vmType The virtual machine to target.
* @throws NullPointerException On null arguments.
* @since 2020/11/28
*/
public
VMLibraryTaskUpToDate
(
VMSpecifier
__vmType
)
throws
NullPointerException
{
if
(
__vmType
==
null
)
throw
new
NullPointerException
(
"NARG"
);
this
.
vmType
=
__vmType
;
}
/**
* {@inheritDoc}
* @since 2020/11/28
*/
@Override
public
boolean
isSatisfiedBy
(
Task
__task
)
{
// Get the times the output was last changed
Set
<
Instant
>
taskOuts
=
new
HashSet
<>();
for
(
File
f
:
__task
.
getOutputs
().
getFiles
().
getFiles
())
taskOuts
.
add
(
Instant
.
ofEpochMilli
(
f
.
lastModified
()));
// Determine if any part of the compiler was not considered up-to-date
for
(
Task
dep
:
this
.
vmType
.
processLibraryDependencies
(
(
VMExecutableTask
)
__task
))
{
for
(
File
f
:
dep
.
getOutputs
().
getFiles
().
getFiles
())
{
Instant
fileTime
=
Instant
.
ofEpochMilli
(
f
.
lastModified
());
// One of the JARs the compiler uses is newer than the JAR we
// made, so this is not up to date!
for
(
Instant
taskOut
:
taskOuts
)
if
(
fileTime
.
compareTo
(
taskOut
)
>
0
)
return
false
;
}
}
// Considered up to date
return
true
;
}
}
buildSrc/src/main/java/cc/squirreljme/plugin/multivm/VMRomTaskAction.java
View file @
37688f5c
...
...
@@ -11,18 +11,15 @@ package cc.squirreljme.plugin.multivm;
import
java.io.File
;
import
java.io.IOException
;