Skip to content

Commit

Permalink
migrate the module 'microsphere-jdk-tools'
Browse files Browse the repository at this point in the history
  • Loading branch information
mercyblitz committed Jun 26, 2024
1 parent 9dd47ad commit 77a2edf
Show file tree
Hide file tree
Showing 11 changed files with 629 additions and 0 deletions.
74 changes: 74 additions & 0 deletions microsphere-jdk-tools/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>io.github.microsphere-projects</groupId>
<artifactId>microsphere-tools-parent</artifactId>
<version>${revision}</version>
<relativePath>../microsphere-tools-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<groupId>io.github.microsphere-projects</groupId>
<artifactId>microsphere-jdk-tools</artifactId>
<version>${revision}</version>
<packaging>jar</packaging>

<name>Microsphere :: Tools :: JDK Tools</name>
<description>Microsphere JDK Tools</description>

<dependencies>

<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<profiles>
<profile>
<id>default-jdk</id>
<activation>
<file>
<exists>${java.home}/../lib/tools.jar</exists>
</file>
</activation>
<dependencies>
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<scope>system</scope>
<version>${java.version}</version>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</profile>
<profile>
<id>osx-jdk</id>
<activation>
<file>
<exists>${java.home}/../Classes/classes.jar</exists>
</file>
</activation>
<dependencies>
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<scope>system</scope>
<version>1.8</version>
<systemPath>${java.home}/../Classes/classes.jar</systemPath>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
120 changes: 120 additions & 0 deletions microsphere-jdk-tools/src/main/java/io/microsphere/tools/Compiler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.microsphere.tools;

import javax.annotation.processing.Processor;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import static java.util.Arrays.asList;

/**
* The Java Compiler
*/
public class Compiler {

private final File sourceDirectory;

private final JavaCompiler javaCompiler;

private final StandardJavaFileManager javaFileManager;

private final Set<Processor> processors = new LinkedHashSet<>();

public Compiler() throws IOException {
this(defaultTargetDirectory());
}

public Compiler(File targetDirectory) throws IOException {
this(defaultSourceDirectory(), targetDirectory);
}

public Compiler(File sourceDirectory, File targetDirectory) throws IOException {
this.sourceDirectory = sourceDirectory;
this.javaCompiler = ToolProvider.getSystemJavaCompiler();
this.javaFileManager = javaCompiler.getStandardFileManager(null, null, null);
this.javaFileManager.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(targetDirectory));
this.javaFileManager.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(targetDirectory));
}

private static File defaultSourceDirectory() {
return new File(defaultRootDirectory(), "src/test/java");
}

private static File defaultRootDirectory() {
return detectClassPath(Compiler.class).getParentFile().getParentFile();
}

private static File defaultTargetDirectory() {
File dir = new File(defaultRootDirectory(), "target/generated-classes");
dir.mkdirs();
return dir;
}

private static File detectClassPath(Class<?> targetClass) {
URL classFileURL = targetClass.getProtectionDomain().getCodeSource().getLocation();
if ("file".equals(classFileURL.getProtocol())) {
return new File(classFileURL.getPath());
} else {
throw new RuntimeException("No support");
}
}

public Compiler processors(Processor... processors) {
this.processors.addAll(asList(processors));
return this;
}

private Iterable<? extends JavaFileObject> getJavaFileObjects(Class<?>... sourceClasses) {
int size = sourceClasses == null ? 0 : sourceClasses.length;
File[] javaSourceFiles = new File[size];
for (int i = 0; i < size; i++) {
File javaSourceFile = javaSourceFile(sourceClasses[i].getName());
javaSourceFiles[i] = javaSourceFile;
}
return javaFileManager.getJavaFileObjects(javaSourceFiles);
}

private File javaSourceFile(String sourceClassName) {
String javaSourceFilePath = sourceClassName.replace('.', '/').concat(".java");
return new File(sourceDirectory, javaSourceFilePath);
}

public boolean compile(Class<?>... sourceClasses) {
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, this.javaFileManager, null,
asList("-parameters", "-Xlint:unchecked", "-nowarn", "-Xlint:deprecation"),
// null,
null, getJavaFileObjects(sourceClasses));
if (!processors.isEmpty()) {
task.setProcessors(processors);
}
return task.call();
}

public JavaCompiler getJavaCompiler() {
return javaCompiler;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Confucius commmons project
*/
package io.microsphere.tools.attach;

import sun.tools.attach.HotSpotVirtualMachine;

/**
* {@link HotSpotVirtualMachine} {@link VirtualMachineCallback}
*
* @author <a href="mailto:[email protected]">Mercy<a/>
* @version 1.0.0
* @see HotSpotVirtualMachine
* @since 1.0.0
*/
public interface HotSpotVirtualMachineCallback<T> extends VirtualMachineCallback<HotSpotVirtualMachine, T> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.microsphere.tools.attach;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;

/**
* Local {@link VirtualMachineTemplate}
*
* @author <a href="mailto:[email protected]">Mercy<a/>
* @version 1.0.0
* @see LocalVirtualMachineTemplate
* @since 1.0.0
*/
public class LocalVirtualMachineTemplate extends VirtualMachineTemplate {

public LocalVirtualMachineTemplate() {
super(String.valueOf(getCurrentProcessId()));
}

private static int getCurrentProcessId() {
int processId = -1;
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
String name = runtimeMXBean.getName();
int index = name.indexOf('@');
if (index > -1) {
String processIdValue = name.substring(0, index);
processId = Integer.parseInt(processIdValue);
}
return processId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.microsphere.tools.attach;

import com.sun.tools.attach.VirtualMachine;

import java.io.IOException;

/**
* {@link VirtualMachine} Callback
*
* @param <T>
* the type of execution callback
* @author <a href="mailto:[email protected]">Mercy<a/>
* @version 1.0.0
* @see VirtualMachine
* @since 1.0.0
*/
public interface VirtualMachineCallback<V extends VirtualMachine, T> {


/**
* Get called by {@link VirtualMachineTemplate#execute(VirtualMachineCallback)}
*
* @param virtualMachine
* {@link VirtualMachine}
* @return execution result
* @throws IOException
* If It's failed to execute some command on virtualMachine , {@link IOException} will be thrown.
*/
T doInVirtualMachine(V virtualMachine) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package io.microsphere.tools.attach;

import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;

import java.io.IOException;

/**
* {@link VirtualMachine} Template Class
*
* @author <a href="mailto:[email protected]">Mercy<a/>
* @version 1.0.0
* @see VirtualMachine
* @since 1.0.0
*/
public class VirtualMachineTemplate {

/**
* Process ID
*/
private final String processId;

/**
* Constructor with {@link Process} ID
*
* @param processId
* {@link Process} ID
*/
public VirtualMachineTemplate(String processId) {
this.processId = processId;
}

/**
* Execute {@link VirtualMachineCallback}
*
* @param callback
* {@link VirtualMachineCallback}
* @param <T>
* @return
* @throws AttachNotSupportedException
* @throws IOException
*/
public final <V extends VirtualMachine, T> T execute(VirtualMachineCallback<V, T> callback) throws AttachNotSupportedException, IOException {
VirtualMachine virtualMachine = null;
T result = null;
try {
virtualMachine = VirtualMachine.attach(processId);
result = callback.doInVirtualMachine((V) virtualMachine);
} finally {
virtualMachine.detach();
}

return result;
}


/**
* Get {@link #processId}
*
* @return processId
* @version 1.0.0
* @since 1.0.0
**/
public String getProcessId() {
return processId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.microsphere.tools;

import io.microsphere.tools.attach.LocalVirtualMachineTemplateTest;
import org.junit.jupiter.api.Test;

import java.io.IOException;

/**
* The Compiler test case
*/
public class CompilerTest {

@Test
public void testCompile() throws IOException {
Compiler compiler = new Compiler();
compiler.compile(LocalVirtualMachineTemplateTest.class);
}
}

Loading

0 comments on commit 77a2edf

Please sign in to comment.