Skip to content

Commit

Permalink
https://github.com/manifold-systems/manifold/issues/628
Browse files Browse the repository at this point in the history
- fix bugs related to compiling android apps using newer JDKs
- display a compile warning regarding usage of manifold-ext where --source version should match the JDK version, otherwise extension classes on the JDK may not compile
  • Loading branch information
rsmckinney committed Oct 29, 2024
1 parent 415514c commit 80080b9
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ private List<String> makeJavacArgs()
else
{
add( "-source" ); add( "1.8" );
// much wrath: add( "-source" ); add( javacPlugin == null ? "1.8" : Source.instance( javacPlugin.getContext() ).name );
}
}};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.comp.*;
Expand All @@ -40,6 +41,7 @@

import java.io.*;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
Expand Down Expand Up @@ -193,6 +195,42 @@ public void init( JavacTask task, String... args )
hijackJavacFileManager();
overrideJavacToolEnter();
task.addTaskListener( this );
warnings();
}

private void warnings()
{
sourceWarning();
}

// Is the --source JDK lower than the compiling JDK?
// If so, report a warning if manifold-ext is in use and if the compiling JDK is 17+. Because extension classes on JDK
// classes such as String may have issues because although the --source is specified the compiler still loads the String
// class directly from the compiling JDK, which includes whatever new changes that may be in String, mainly super types
// type refs elsewhere in the class. You see, --source only prevents compiling source code from referencing types, methods, fields, etc.
// from the JDK class that are not in the older --source version of the class -- it is just the newer type information that the
// compiler prohibits the use of, but the String type itself is still there with all the new stuff in it. Because a
// manifold extension on String loads the type to generate the stub source, the generated class has all the new type info
// in it, regardless of whatever --source may be.
private void sourceWarning()
{
if( !isExtensionsEnabled() || !JreUtil.isJava9orLater() )
{
return;
}

String source = Source.instance( getContext() ).name;
int sourceValue = new BigDecimal( source ).intValue();
if( sourceValue < JreUtil.JAVA_VERSION )
{
getIssueReporter().reportWarning(
"\n" +
"Usage of `manifold-ext` compiling with JDK " + JreUtil.JAVA_VERSION + " may not support source version " + source + " if\n" +
"your application uses extensions on JRE classes like String, List, etc. Generally,\n" +
"with JDK 11 or greater it is best to compile --source X with JDK X. If you experience\n" +
"compile errors corresponding with JRE classes, please consider changing your compiler\n" +
"to JDK " + source + " or changing --source to " + JreUtil.JAVA_VERSION + ". Otherwise, ignore this message.\n" );
}
}

private void overrideJavacToolEnter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ private SrcClass makeSrcClass( String fqn, SrcClass enclosing, Symbol.ClassSymbo
}
for( Type iface: classSymbol.getInterfaces() )
{
if( iface.tsym.getQualifiedName().toString().startsWith( "java.lang.constant." ) )
{
// android: for some reason android does not resolve this package, i don't like you android
continue;
}
srcClass.addInterface( makeNestedType( iface ) );
}
if( withMembers )
Expand Down Expand Up @@ -369,6 +374,11 @@ private void addMethod( IModule module, SrcClass srcClass, Symbol.MethodSymbol m
for( int i = 0; i < parameters.size(); i++ )
{
Symbol.VarSymbol param = parameters.get( i );
if( param.type.toString().equals( "java.lang.AbstractStringBuilder" ) )
{
// android: doesn't resolve AbstractStringBuilder with extended classes while compiling their source, such as when String is extended locally
return;
}
String paramName = recordFields == null ? param.flatName().toString() : recordFields.get( i ).flatName().toString();
SrcParameter srcParam = new SrcParameter( paramName, makeSrcType( param.type, method, TargetType.METHOD_FORMAL_PARAMETER, i ) );
srcMethod.addParam( srcParam );
Expand Down Expand Up @@ -705,6 +715,11 @@ private void addAnnotation( SrcType srcType, Attribute.TypeCompound attr )
// Since java 10 we have to keep these out of stubbed java source
return;
}
if( fqn.startsWith( "jdk.internal.vm.annotation." ) )
{
// Since java 10 we have to keep these out of stubbed java source
return;
}
SrcAnnotationExpression annoExpr = new SrcAnnotationExpression( fqn );
for( Pair<Symbol.MethodSymbol, Attribute> value: attr.values )
{
Expand Down Expand Up @@ -902,6 +917,16 @@ private void addAnnotations( SrcAnnotated<?> srcAnnotated, Symbol symbol )
// Since java 10 we have to keep these out of stubbed java source
continue;
}
if( fqn.startsWith( "jdk.internal.vm.annotation." ) )
{
// Since java 12 we have to keep these out of stubbed java source
continue;
}
if( fqn.startsWith( "<" ) )
{
// android: avoid errant types such as "<any>"
continue;
}
if( fqn.equals( "jdk.internal.ValueBased" ) )
{
// Since java 16 we have to keep these out of stubbed java source
Expand Down
59 changes: 35 additions & 24 deletions manifold-util/src/main/java/manifold/util/NecessaryEvilUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,22 @@ private static void openRuntimeModules( ReflectUtil.MethodRef addExportsOrOpens,
// Module: java.base
//
Object /*Module*/ javaBaseModule = ReflectUtil.method( Class.class, "getModule" ).invoke( String.class );
addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.loader", manifoldModule, true, true );
addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.misc", manifoldModule, true, true );
addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.module", manifoldModule, true, true );
addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.vm", manifoldModule, true, true );
addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.vm.annotation", manifoldModule, true, true );
addExportsOrOpens.invoke( javaBaseModule, "java.lang", manifoldModule, true, true );
addExportsOrOpens.invoke( javaBaseModule, "java.lang.invoke", manifoldModule, true, true );
addExportsOrOpens.invoke( javaBaseModule, "java.lang.module", manifoldModule, true, true );
addExportsOrOpens.invoke( javaBaseModule, "java.lang.reflect", manifoldModule, true, true ); // for jailbreak
addExportsOrOpens.invoke( javaBaseModule, "java.net", manifoldModule, true, true );

// addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.loader", manifoldModule, true, true );
// addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.misc", manifoldModule, true, true );
// addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.module", manifoldModule, true, true );
// addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.vm", manifoldModule, true, true );
// addExportsOrOpens.invoke( javaBaseModule, "jdk.internal.vm.annotation", manifoldModule, true, true );
// addExportsOrOpens.invoke( javaBaseModule, "java.lang", manifoldModule, true, true );
// addExportsOrOpens.invoke( javaBaseModule, "java.lang.invoke", manifoldModule, true, true );
// addExportsOrOpens.invoke( javaBaseModule, "java.lang.module", manifoldModule, true, true );
// addExportsOrOpens.invoke( javaBaseModule, "java.lang.reflect", manifoldModule, true, true ); // for jailbreak
// addExportsOrOpens.invoke( javaBaseModule, "java.net", manifoldModule, true, true );
//noinspection unchecked
Set<String> packages = (Set<String>)ReflectUtil.method( javaBaseModule, "getPackages" ).invoke();
for( String pkg : packages )
{
addExportsOrOpens.invoke( javaBaseModule, pkg, manifoldModule, true, true );
}

//
// Module: java.desktop (needed for testing manifold IJ plugin)
Expand All @@ -158,19 +163,25 @@ private static void openCompilerModules( ReflectUtil.MethodRef addExportsOrOpens
//
Object /*Module*/ jdkCompilerModule = ReflectUtil.method( Class.class, "getModule" )
.invoke( ReflectUtil.type( "com.sun.tools.javac.code.Symbol", true ) );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.api", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.code", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.comp", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.file", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.jvm", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.main", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.model", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.parser", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.platform", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.processing", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.resources", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.tree", manifoldModule, true, true );
addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.util", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.api", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.code", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.comp", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.file", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.jvm", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.main", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.model", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.parser", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.platform", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.processing", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.resources", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.tree", manifoldModule, true, true );
// addExportsOrOpens.invoke( jdkCompilerModule, "com.sun.tools.javac.util", manifoldModule, true, true );
//noinspection unchecked
Set<String> packages = (Set<String>)ReflectUtil.method( jdkCompilerModule, "getPackages" ).invoke();
for( String pkg : packages )
{
addExportsOrOpens.invoke( jdkCompilerModule, pkg, manifoldModule, true, true );
}

//
// Module: jdk.javadoc
Expand Down

0 comments on commit 80080b9

Please sign in to comment.