Skip to content

Commit f93b4b7

Browse files
committed
Force classes to define a serialVersionUID and make sure it's of type
long. Signed-off-by: Akintayo A. Olusegun <akintayo.segun@gmail.com>
1 parent b178972 commit f93b4b7

3 files changed

Lines changed: 72 additions & 183 deletions

File tree

pom.xml

Lines changed: 19 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33

44
<groupId>ng.com.idempotent</groupId>
55
<artifactId>InMemoryJavaCompiler</artifactId>
6-
<version>1.5.0</version>
6+
<version>1.6.0</version>
77
<packaging>jar</packaging>
88
<url>https://github.com/segun/InMemoryJavaCompiler</url>
99

1010
<name>InMemoryJavaCompiler</name>
1111
<description>Small utility to compile java code in memory</description>
12-
12+
1313
<properties>
14-
<maven.compiler.source>1.8</maven.compiler.source>
15-
<maven.compiler.target>1.8</maven.compiler.target>
14+
<maven.compiler.source>1.8</maven.compiler.source>
15+
<maven.compiler.target>1.8</maven.compiler.target>
1616
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1717
<maven-compiler-plugin.version>3.2</maven-compiler-plugin.version>
1818
<nexus-staging-maven-plugin.version>1.6.3</nexus-staging-maven-plugin.version>
@@ -41,17 +41,13 @@
4141
<url>https://github.com/segun/InMemoryJavaCompiler</url>
4242
<connection>scm:git:git://github.com/segun/InMemoryJavaCompiler</connection>
4343
<developerConnection>scm:git:git@github.com:segun/InMemoryJavaCompiler.git</developerConnection>
44-
<tag>HEAD</tag>
45-
</scm>
44+
<tag>HEAD</tag>
45+
</scm>
4646

4747
<distributionManagement>
48-
<snapshotRepository>
49-
<id>ossrh</id>
50-
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
51-
</snapshotRepository>
5248
<repository>
53-
<id>ossrh</id>
54-
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
49+
<id>segun-maven-repo</id>
50+
<url>https://api.bintray.com/maven/segun/segun-maven-repo/InMemoryJavaCompiler/;publish=1</url>
5551
</repository>
5652
</distributionManagement>
5753

@@ -71,17 +67,17 @@
7167
</developers>
7268

7369
<dependencies>
74-
<dependency>
75-
<groupId>org.slf4j</groupId>
76-
<artifactId>slf4j-api</artifactId>
77-
<version>${slf4j.version}</version>
78-
</dependency>
79-
<dependency>
80-
<groupId>org.slf4j</groupId>
81-
<artifactId>slf4j-jdk14</artifactId>
82-
<version>${slf4j.version}</version>
83-
<scope>test</scope>
84-
</dependency>
70+
<dependency>
71+
<groupId>org.slf4j</groupId>
72+
<artifactId>slf4j-api</artifactId>
73+
<version>${slf4j.version}</version>
74+
</dependency>
75+
<dependency>
76+
<groupId>org.slf4j</groupId>
77+
<artifactId>slf4j-jdk14</artifactId>
78+
<version>${slf4j.version}</version>
79+
<scope>test</scope>
80+
</dependency>
8581
<dependency>
8682
<groupId>junit</groupId>
8783
<artifactId>junit</artifactId>
@@ -92,34 +88,11 @@
9288

9389
<build>
9490
<plugins>
95-
<plugin>
96-
<groupId>org.codehaus.mojo</groupId>
97-
<artifactId>cobertura-maven-plugin</artifactId>
98-
<version>2.7</version>
99-
<configuration>
100-
<formats>
101-
<format>html</format>
102-
<format>xml</format>
103-
</formats>
104-
<check />
105-
</configuration>
106-
</plugin>
10791
<plugin>
10892
<groupId>org.apache.maven.plugins</groupId>
10993
<artifactId>maven-compiler-plugin</artifactId>
11094
<version>${maven-compiler-plugin.version}</version>
11195
</plugin>
112-
<plugin>
113-
<groupId>org.sonatype.plugins</groupId>
114-
<artifactId>nexus-staging-maven-plugin</artifactId>
115-
<version>${nexus-staging-maven-plugin.version}</version>
116-
<extensions>true</extensions>
117-
<configuration>
118-
<serverId>ossrh</serverId>
119-
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
120-
<autoReleaseAfterClose>true</autoReleaseAfterClose>
121-
</configuration>
122-
</plugin>
12396
<plugin>
12497
<groupId>org.apache.maven.plugins</groupId>
12598
<artifactId>maven-release-plugin</artifactId>
Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package ng.com.idempotent;
22

3-
import java.io.ByteArrayOutputStream;
43
import java.io.File;
5-
import java.io.ObjectOutputStream;
4+
import java.io.InvalidClassException;
5+
import java.lang.reflect.Field;
66
import java.lang.reflect.Method;
7+
import java.lang.reflect.Modifier;
78
import java.lang.reflect.Parameter;
89
import java.nio.file.Files;
910
import java.nio.file.Paths;
@@ -23,9 +24,9 @@ public final class Compiler {
2324
* /home/dev/src/java/com/test/sjb/HelloWorld.java
2425
* @param fullyQualifiedClassName the fully qualified name of the class e.g
2526
* com.test.sjb.HelloWorld
26-
* @return a HashMap containing the base64 encoded string of the
27-
* instance of the class and a json docs of the name of the class, methods
28-
* and parameters. The returned String will be uploaded to the blockchain.
27+
* @return a HashMap containing the base64 encoded string of the instance of
28+
* the class and a json docs of the name of the class, methods and
29+
* parameters. The returned String will be uploaded to the blockchain.
2930
* @throws Exception
3031
*/
3132
public static final HashMap<String, Object> compile(File source, String fullyQualifiedClassName) throws Exception {
@@ -38,51 +39,86 @@ public static final HashMap<String, Object> compile(File source, String fullyQua
3839
* @param sourceCode a String containing the source code
3940
* @param fullyQualifiedClassName the fully qualified name of the class e.g
4041
* com.test.sjb.HelloWorld
41-
* @return a HashMap containing the base64 encoded string of the
42-
* instance of the class and a json docs of the name of the class, methods
43-
* and parameters. The returned String will be uploaded to the blockchain.
42+
* @return a HashMap containing the base64 encoded string of the instance of
43+
* the class and a json docs of the name of the class, methods and
44+
* parameters. The returned String will be uploaded to the blockchain.
4445
* @throws Exception
4546
*/
4647
public static final HashMap<String, Object> compile(String sourceCode, String fullyQualifiedClassName) throws Exception {
4748
InMemoryJavaCompiler compiler = InMemoryJavaCompiler.newInstance();
4849
Class<?> compiled = compiler.compile(fullyQualifiedClassName, sourceCode);
50+
51+
Class[] interfaces = compiled.getInterfaces();
52+
boolean hasSmartBean = false;
53+
for (Class c : interfaces) {
54+
if (c.getName().contains("SmartBean")) {
55+
hasSmartBean = true;
56+
break;
57+
}
58+
}
59+
60+
if (!hasSmartBean) {
61+
throw new InvalidClassException(fullyQualifiedClassName + " does not implement the SmartBean Interface. All Smart Classes must implement the smart bean interface");
62+
}
63+
64+
Field f = compiled.getDeclaredField("serialVersionUID");
65+
System.out.println("Found Field: [" + f +"]");
66+
if (f == null) {
67+
throw new InvalidClassException(fullyQualifiedClassName + " does not have a variable called serialVersionUID. All Smart Classes must implement have this variable");
68+
}
4969

70+
try {
71+
int foundMods = f.getModifiers();
72+
73+
if(!Modifier.isFinal(foundMods)) {
74+
throw new InvalidClassException(fullyQualifiedClassName + " serialVersionUID does not have a final modifier. Please make serialVersionUID static final");
75+
}
76+
77+
if(!Modifier.isStatic(foundMods)) {
78+
throw new InvalidClassException(fullyQualifiedClassName + " serialVersionUID does not have a static modifier. Please make serialVersionUID static final");
79+
}
80+
81+
if(!f.getType().getName().equals("long")) {
82+
throw new InvalidClassException(fullyQualifiedClassName + " serialVersionUID must be of type long");
83+
}
84+
} catch(Exception e) {
85+
throw new InvalidClassException(e.getMessage());
86+
}
87+
5088
CompiledCode cc = compiler.classLoader.customCompiledCode.get(fullyQualifiedClassName);
51-
byte[] byteCode = cc.getByteCode();
52-
89+
byte[] byteCode = cc.getByteCode();
90+
5391
HashMap<String, Object> docsMap = new HashMap<>();
5492
docsMap.put("name", fullyQualifiedClassName);
5593

5694
List<HashMap<String, Object>> methodsList = new ArrayList<>();
5795
Method[] methods = compiled.getMethods();
5896

59-
for (Method m : methods) {
97+
for (Method m : methods) {
6098
String declaringClass = m.getDeclaringClass().getName();
6199
if (declaringClass.equals(fullyQualifiedClassName)) {
62100
HashMap<String, Object> methodsMap = new HashMap<>();
63101
String name = m.getName();
64102
methodsMap.put("name", name);
65103

66104
Parameter[] parameters = m.getParameters();
67-
List<HashMap<String, String>> parametersList = new ArrayList<>();
105+
List<String> parametersList = new ArrayList<>();
68106

69107
for (Parameter p : parameters) {
70-
HashMap<String, String> parametersMap = new HashMap<>();
71-
parametersMap.put("type", p.getType().getCanonicalName());
72-
parametersList.add(parametersMap);
108+
parametersList.add(p.getType().getCanonicalName());
73109
}
74110
methodsMap.put("parameters", parametersList);
75111
methodsMap.put("returnType", m.getReturnType().getCanonicalName());
76112
methodsList.add(methodsMap);
77113
}
78114
}
79-
115+
80116
docsMap.put("methods", methodsList);
81117

82118
HashMap<String, Object> returnValue = new HashMap<>();
83119
returnValue.put("byteCode", Base64.getEncoder().encodeToString(byteCode));
84120
returnValue.put("documentation", docsMap);
85-
121+
86122
return returnValue;
87123
}
88124
}

src/test/java/org/mdkt/compiler/InMemoryJavaCompilerTest.java

Lines changed: 0 additions & 120 deletions
This file was deleted.

0 commit comments

Comments
 (0)