Bug? rename library OkHttp.jar to okhttp.jar (about classpath on linux)

Discussion in 'B4J Bugs & Wishlist' started by icefairy333, Jun 13, 2018.

  1. icefairy333

    icefairy333 Active Member Licensed User

    after compile the project with #MergeLibraries: False ,the ide show
    Code:
    The following libraries should be distributed in the libs folder:
     jCore.jar jOkHttpUtils2.jar jServer.jar 
    jfx.jar okhttp.jar jstringutils.jar json.jar okhttp-3.5.0.jar okio-1.11.0.jar jetty_b4j.jar c3p0-0.9.5.2.jar c3p0-oracle-thin-extras-0.9.5.2.jar mchange-commons-java-0.2.11.jar
    but the real filename in the library directory is "OkHttp.jar",so with Linux it will cause classNotFound exception,please modify the name to lowercase in the library directory before publish B4J , Thank you.
    I use this code to copy the jar auto:
    Code:
    'WebPlus Handler自动扫描器
    Sub Class_Globals
        
    Private jr As jarUtils
        
    Type actionts(ak As String,sth As Boolean)
    End Sub

    'init and add all handler(which "handler" in names),you should defined a var named "actionkey" in handler else I will use the name before "handler"
    'add:public sth as boolean=true 'when you want the handler to be SingleThreadHandler
    Public Sub Initialize(ser As Server)
        jr.Initialize
        
    Dim clsList As List
        
    Dim srcpath As String=jr.SrcPath
        
    If srcpath.ToLowerCase.EndsWith(".jar"Then
            
    'find class from jar
            clsList=jr.GetAllClassesNamesFromJar(jr.pkgName,srcpath)
        
    Else
            clsList=jr.GetAllClassesNames
        
    End If
       
        
    If clsList.IsInitialized And clsList.Size>0 Then
            
    For Each k As String In clsList
                
    If k.IndexOf("handler")>-1 And k.IndexOf("$")=-1 Then
                    
    Dim actKey As actionts=GetActionKeyTS(k)
                    
    If actKey.ak.Length<1 Then
                        actKey.ak=
    "/"&k.Replace("handler","")
                        G.mLog(
    "add handler:"&actKey.ak&" with default handler:"&k)
                    
    Else
                        G.mLog(
    "add handler:"&actKey.ak&" with handler:"&k)
                    
    End If
                   
                    ser.AddHandler(actKey.ak,k,actKey.sth)
                
    End If
            
    Next
        
    Else
            
    Log("clsList not init or MergeLibraries is set to true,if you want to using this utils you should set MergeLibraries to false")
        
    End If
    '    #if release
        printStartCmdLine
    '    #End If
       
    End Sub
    Private Sub printStartCmdLine
        
    File.WriteString(File.DirApp,"webplus.pid",jr.GetCurrentPid)
        
    If File.Exists(File.DirApp,"webplusstarter.bat")=False Then
            
    '如果启动脚本不存在则进入生成环节
            Dim srcpath As String=jr.SrcPath.ToLowerCase
            
    Dim sb,sblinux As StringBuilder
            
    Dim cplst As List
            sb.Initialize
            sblinux.Initialize
            sblinux.Append(
    "echo startingProject").Append(CRLF)
            sb.Append(
    $"@echo off
    color 0a
    title "webplus Project Starter"
    cd /d %~dp0
    set curpath=%cd%
    echo "enter work dir:%curpath%"
    echo "kill java.exe"
    for /f "tokens=1" %%i in (webplus.pid) do taskkill /f /pid %%i
    "$
    )
            
    Dim jarname As String=getJarFilenameFromOBjects
            
    Log("jarname:"&jarname)
            
    If srcpath.EndsWith(".jar"Then
                sb.Append(
    "java.exe -jar "&jarname).Append(CRLF)
            
    Else
                
    Dim cpstr As String=GetSystemProperty("java.class.path","")
                
    Dim enc As String=GetSystemProperty("file.encoding","unknow")
                sb.Append(
    "java.exe -Dfile.encoding=").Append(enc).Append(" -cp ")
                
    Try
                    
    If cpstr.Length>0 Then
                        cplst=
    Regex.Split(";",cpstr)
                        
    If cplst.IsInitialized=False Then cplst.Initialize
                        
    For Each s As String In cplst
                            
    If s.Length>0 Then
                                sb.Append(
    $""${getFilePathinLibs(getRealFileName(s))}";"$)
                            
    End If
                        
    Next
                        sb=sb.Remove(sb.Length-
    1,sb.Length)
                        sb.Append(
    " -jar "&getJarFilenameFromOBjects).Append(CRLF)
                       
    '                    sb.Append(" "&jr.pkgName&".main").Append(CRLF)
                    End If
                   
                
    Catch
                    
    Log(LastException)
                
    End Try
                
    Try
                    
    If File.Exists(File.DirApp,"libs")=False Then File.MakeDir(File.DirApp,"libs")
                    
    Dim libsdir As String=File.Combine(File.DirApp,"libs")
                    
    For Each s As String In cplst
                        
    If File.Exists("",s) And File.IsDirectory("",s)=False And s.ToLowerCase.EndsWith(".jar"Then
                            
    '如果文件存在且不是目录且是jar文件
                            File.Copy("",s,libsdir,getRealFileName(s))
                        
    End If
                    
    Next
                
    Catch
                    
    Log("copy libs error:"&LastException)
                
    End Try
               
            
    End If
            sb.Append(
    "echo ""webplus project run completed ok""").Append(CRLF)
            
    Dim tw As TextWriter
            tw.Initialize2(
    File.OpenOutput(File.DirApp,"webplusstarter.bat",False),"GBK")
            tw.WriteLine(sb.ToString)
            tw.Flush
            tw.Close
            sblinux.Append(
    "java -jar "&getJarFilenameFromOBjects).Append(" &").Append(CRLF)
            sblinux.Append(
    "echo project started").Append(CRLF)
            tw.Initialize2(
    File.OpenOutput(File.DirApp,"webplusstarter.sh",False),"UTF-8")
            tw.WriteLine(sblinux.ToString)
            tw.Flush
            tw.Close
            
    Log("项目启动脚本:"&File.Combine(File.DirApp,"webplusstarter.bat"))
        
    End If
       
       
       
    End Sub
    Sub getRealFileName(s As StringAs String
        
    Dim path As String=File.GetFileParent(s)
        
    Dim fn As String=File.GetName(s)
        
    If path.Length>0 Then
            
    Dim lst As List=File.ListFiles(path)
            
    For Each s As String In lst
                
    If s.EqualsIgnoreCase(fn) Then
                    
    Return s
                
    End If
            
    Next
        
    End If
        
    Return ""
    End Sub
    Private Sub getJarFilenameFromOBjects As String
        
    Dim lst As List
        
    #if release
        lst=File.ListFiles(File.DirApp)
        #Else
        lst=File.ListFiles(File.Combine(File.DirApp,"../"))
        
    #End If
       
        
    For Each s As String In lst
            
    #if release
            If s.ToLowerCase.EndsWith(".jar") Then
                Return File.GetName(s)
            End If
            #Else
            If s.ToLowerCase.EndsWith(".b4j") Then
                Return File.GetName(s).Replace(".b4j",".jar")
            End If
            
    #End If
           
        
    Next
    End Sub
    Private Sub getFilePathinLibs(s As StringAs String
        
    If s.Length>0 Then Return File.Combine(File.Combine("%curpath%","libs"),File.GetName(s)) Else Return ""
    End Sub
    Private Sub GetActionKeyTS(clsName As StringAs actionts
        
    Dim jo As JavaObject
        
    Dim ret As actionts
        ret.Initialize
        
    Dim pkg As String=jr.pkgName&"."&clsName
        
    Try
            jo=jo.InitializeNewInstance(pkg,
    Null)
            
    #if release
            jo.RunMethod("_class_globals",Null) 'release mode
            #else
                jo.RunMethod("_class_globals",Array As Object(Null)) 'debug mode
            
    #End If
           
            ret.ak=jo.GetField(
    "_actionkey")
        
    Catch
    '        Log(LastException)
            ret.ak=""
        
    End Try
        
    Try
            ret.sth=jo.GetField(
    "_sth")
        
    Catch
            ret.sth=
    False
        
    End Try
        
    Return ret
    End Sub
    file jarUtils
    Code:
    'Class module

    Sub Class_Globals

        
    Private jo As JavaObject

    End Sub


    'Initializes the object. You can add parameters to this method if needed.

    Public Sub Initialize

        jo=Me

    End Sub

    'return a list includes all classname

    Public Sub GetAllClassesNames As List

        
    Dim clsList As List=GetAllClasses(getpkgName)

        
    For i=0 To clsList.Size-1

            
    Dim clsName As String=clsList.Get(i)

            clsName=clsName.SubString2(clsName.LastIndexOf(
    ".")+1,clsName.Length)

            clsName=clsName.Replace(
    "class ","")

            clsList.Set(i,clsName)

        
    Next

        
    Return clsList

    End Sub

    Public Sub GetAllClassesNamesFromJar(pkgName As String,jarpath As StringAs List

        
    Dim clsList As List=GetAllClassesFromJar(pkgName,jarpath)

        
    For i=0 To clsList.Size-1

            
    Dim clsName As String=clsList.Get(i)

            clsName=clsName.SubString2(clsName.LastIndexOf(
    ".")+1,clsName.Length)

            clsName=clsName.Replace(
    "class ","")

            clsList.Set(i,clsName)

        
    Next

        
    Return clsList

    End Sub


    'map:type,name

    Public Sub getClassAllProperties(cls As Object) As List

        
    Dim lst As List

        jo=Me

        lst=jo.RunMethod(
    "getClassAllProperties",Array As Object(cls))

        
    Return lst

    End Sub

    'map:type,name

    Public Sub getClassPublicProperties(cls As Object) As List

        
    Dim lst As List

        jo=Me

        lst=jo.RunMethod(
    "getClassPublicProperties",Array As Object(cls))

        
    Return lst

    End Sub

    Public Sub getClassMethods(cls As Object) As List

        
    Dim lst As List

        jo=Me

        lst=jo.RunMethod(
    "getClassMethods",Array As Object(cls))

        
    Return lst

    End Sub

    'you must load at least one class before using this method

    Public Sub GetAllClasses(pkgname As StringAs List

        
    Dim lst As List

        jo=Me

        lst=jo.RunMethod(
    "getClasses",Array As Object(pkgname))

        
    If lst.IsInitialized=False Or lst.Size=0 Then

            lst.Initialize

            
    Log("class list empty")

        
    End If

        
    Return lst

    End Sub

    Public Sub GetAllClassesFromJar(pkgname As String,path As StringAs JavaObject

        
    Dim lst As List

        jo=Me

        lst=jo.RunMethod(
    "getClassesFromJar",Array As Object(pkgname,path))

        
    If lst.IsInitialized=False Or lst.Size=0 Then

            lst.Initialize

            
    Log("class list empty")

        
    End If

        
    Return lst

    End Sub

    Public Sub getThisClass As JavaObject

        jo=Me

        
    Return jo.RunMethod("getClass",Null)

    End Sub

    Public Sub getNativeClass(b4xClass As Object) As JavaObject

        jo=b4xClass

        
    Return jo.RunMethod("getClass",Null)

    End Sub

    Public Sub getClassByName(fullname As StringAs JavaObject

        jo=Me

        
    Return jo.RunMethod("getClassByName",Array As String(fullname))

    End Sub

    'return the jar file path when MergeLibraries=true

    'return the directory path when MergeLibraries=false or debug mode

    'path based on system(AbsolutePath)

    Public Sub getSrcPath As String

        jo=Me

        
    Return jo.RunMethod("getSrcPath",Null)

    End Sub

    'get package name of this app

    Public Sub getpkgName As String

        jo=Me

        
    Dim pkg As String=jo.RunMethod("getpkgName",Array As Object(getThisClass))

        
    Return pkg

    End Sub

    Public Sub GetCurrentPid As Int

        
    Dim jo As JavaObject

        jo=jo.InitializeStatic(
    "java.lang.management.ManagementFactory").RunMethodJO("getRuntimeMXBean",Null)

        
    Dim name As String=jo.RunMethod("getName",Null)

        
    Dim ns() As String=Regex.Split("@",name)

        
    Return ns(0)

    End Sub


    #If java

    import java.io.File;

    import java.lang.reflect.Field; 

    import java.lang.reflect.Method;

    import java.io.FileFilter;

    import java.io.IOException;

    import java.net.JarURLConnection;

    import java.net.URL;

    import java.net.URLDecoder;

    import java.util.ArrayList;

    import java.util.Enumeration;

    import java.util.LinkedHashSet;

    import java.util.List;

    import java.util.Set;

    import java.util.jar.JarEntry;

    import java.util.jar.JarFile;



    import anywheresoftware.b4a.BA;

    import anywheresoftware.b4a.keywords.Common;

    import anywheresoftware.b4a.objects.collections.Map;


        public static ArrayList<Map.MyMap> getClassAllProperties(Class clazz) { 

            Field[] fields = clazz.getDeclaredFields(); 

            ArrayList<Map.MyMap> lst=new ArrayList<Map.MyMap>();

            for (int i=0; i<fields.length; i++) { 

                Field field=fields[i];

                lst.add(Common.createMap(new Object[]{(Object)"type",field.getType().getSimpleName(),(Object)"name",field.getName()}).getObject()); 

            } 

            return lst; 

        } 

        public static ArrayList<Map.MyMap> getClassPublicProperties(Class clazz) { 

            Field[] fields = clazz.getFields(); 

            ArrayList<Map.MyMap> lst=new ArrayList<Map.MyMap>();

            for (int i=0; i<fields.length; i++) { 

                Field field=fields[i];

                lst.add(Common.createMap(new Object[]{(Object)"type",field.getType().getSimpleName(),(Object)"name",field.getName()}).getObject()); 

            } 

            return lst; 

        } 

        public String getSrcPath() {

            URL url=getClass().getProtectionDomain().getCodeSource().getLocation();

            String path="";

            try {

                path=URLDecoder.decode(url.getPath(), "utf-8");

                File file=new File(path);

                path=file.getAbsolutePath();

            } catch (Exception e) {

                // TODO: handle exception

            }

            return path;


        }

        public List<Method> getClassMethods(Class c){

            Method m[] = c.getMethods(); // 取得全部的方法

            List <Method> result = new ArrayList<Method>(); 

            if(m!=null){

                for (int i=0;i<m.length;i++){

                    result.add(m[i]);

                }

            }

            return result;

        }

        public String getpkgName(Class c){

            return c.getPackage().getName();

        }

        public Class<?> getClassByName(String n){

            try { 

                //添加到classes 

                return Class.forName(n);

            } catch (ClassNotFoundException e) { 

                e.printStackTrace(); 

            } 

            return null;

        }

    /**

    * 类相关的工具类

    *

    * @author <a href="mailto:ohergal@gmail.com">ohergal</a>

    *

    */

        /**

         * 取得某个接口下所有实现这个接口的类

         * */

        public List<Class> getAllClassByInterface(Class c) {

                List<Class>  returnClassList = null;


                if(c.isInterface()) {

                    // 获取当前的包名

                    String packageName = c.getPackage().getName();

                    // 获取当前包下以及子包下所以的类

                    List<Class<?>> allClass = getClasses(packageName);

                    if(allClass != null) {

                        returnClassList = new ArrayList<Class>();

                        for(Class classes : allClass) {

                            // 判断是否是同一个接口

                            if(c.isAssignableFrom(classes)) {

                                // 本身不加入进去

                                if(!c.equals(classes)) {

                                    returnClassList.add(classes);       

                                }

                            }

                        }

                    }

                }


                return returnClassList;

            }



        /*

         * 取得某一类所在包的所有类名 不含迭代

         */

        public String[] getPackageAllClassName(String classLocation, String packageName){

            //将packageName分解

            String[] packagePathSplit = packageName.split("[.]");

            String realClassLocation = classLocation;

            int packageLength = packagePathSplit.length;

            for(int i = 0; i< packageLength; i++){

                realClassLocation = realClassLocation + File.separator+packagePathSplit[i];

            }

            File packeageDir = new File(realClassLocation);

            if(packeageDir.isDirectory()){

                String[] allClassName = packeageDir.list();

                return allClassName;

            }

            return null;

        }


        /**

         * 从包package中获取所有的Class

         * @param pack

         * @return

         */

        public List<Class<?>> getClasses(String packageName){


            //第一个class类的集合

            List<Class<?>> classes = new ArrayList<Class<?>>();

            //是否循环迭代

            boolean recursive = true;

            //获取包的名字 并进行替换

            String packageDirName = packageName.replace('.', '/');

            //定义一个枚举的集合 并进行循环来处理这个目录下的things

            Enumeration<URL> dirs;

            try {

                dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);

                //循环迭代下去

                while (dirs.hasMoreElements()){

                    //获取下一个元素

                    URL url = dirs.nextElement();

                    //得到协议的名称

                    String protocol = url.getProtocol();

                    //如果是以文件的形式保存在服务器上

                    if ("file".equals(protocol)) {

                        //获取包的物理路径

                        String filePath = URLDecoder.decode(url.getFile(), "UTF-8");

                        //以文件的方式扫描整个包下的文件 并添加到集合中

                        findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);

                    } else if ("jar".equals(protocol)){

                        //如果是jar包文件

                        //定义一个JarFile

                        JarFile jar;

                        try {

                            //获取jar

                            jar = ((JarURLConnection) url.openConnection()).getJarFile();

                            //从此jar包 得到一个枚举类

                            Enumeration<JarEntry> entries = jar.entries();

                            //同样的进行循环迭代

                            while (entries.hasMoreElements()) {

                                //获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件

                                JarEntry entry = entries.nextElement();

                                String name = entry.getName();

                                //如果是以/开头的

                                if (name.charAt(0) == '/') {

                                    //获取后面的字符串

                                    name = name.substring(1);

                                }

                                //如果前半部分和定义的包名相同

                                if (name.startsWith(packageDirName)) {

                                    int idx = name.lastIndexOf('/');

                                    //如果以"/"结尾 是一个包

                                    if (idx != -1) {

                                        //获取包名 把"/"替换成"."

                                        packageName = name.substring(0, idx).replace('/', '.');

                                    }

                                    //如果可以迭代下去 并且是一个包

                                    if ((idx != -1) || recursive){

                                        //如果是一个.class文件 而且不是目录

                                        if (name.endsWith(".class") && !entry.isDirectory()) {

                                            //去掉后面的".class" 获取真正的类名

                                            String className = name.substring(packageName.length() + 1, name.length() - 6);

                                            try {

                                                //添加到classes

                                                classes.add(Class.forName(packageName + '.' + className));

                                            } catch (ClassNotFoundException e) {

                                                e.printStackTrace();

                                            }

                                          }

                                    }

                                }

                            }

                        } catch (IOException e) {

                            e.printStackTrace();

                        }

                    }

                }

            } catch (IOException e) {

                e.printStackTrace();

            }


            return classes;

        }

        public List<Class<?>> getClassesFromJar(String packageName,String path){

            //第一个class类的集合

            JarFile jar;

            String packageDirName = packageName.replace('.', '/');

            ArrayList<Class<?>> classes=new ArrayList<>();

            boolean recursive=true;

            try {

                //获取jar

                jar =new JarFile(path);

                //从此jar包 得到一个枚举类

                Enumeration<JarEntry> entries = jar.entries();

                //同样的进行循环迭代

                while (entries.hasMoreElements()) {

                    //获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件

                    JarEntry entry = entries.nextElement();

                    String name = entry.getName();

                    //如果是以/开头的

                    if (name.charAt(0) == '/') {

                        //获取后面的字符串

                        name = name.substring(1);

                    }

                    //如果前半部分和定义的包名相同

                    if (name.startsWith(packageDirName)) {

                        int idx = name.lastIndexOf('/');

                        //如果以"/"结尾 是一个包

                        if (idx != -1) {

                            //获取包名 把"/"替换成"."

                            packageName = name.substring(0, idx).replace('/', '.');

                        }

                        //如果可以迭代下去 并且是一个包

                        if ((idx != -1) || recursive){

                            //如果是一个.class文件 而且不是目录

                            if (name.endsWith(".class") && !entry.isDirectory()) {

                                //去掉后面的".class" 获取真正的类名

                                String className = name.substring(packageName.length() + 1, name.length() - 6);

                                try {

                                    //添加到classes

                                    classes.add(Class.forName(packageName + '.' + className));

                                } catch (ClassNotFoundException e) {

                                    e.printStackTrace();

                                }

                              }

                        }

                    }

                }

            } catch (IOException e) {

                e.printStackTrace();

            }

            return classes;

        }

        /**

         * 以文件的形式来获取包下的所有Class

         * @param packageName

         * @param packagePath

         * @param recursive

         * @param classes

         */

        public void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, List<Class<?>> classes){

            //获取此包的目录 建立一个File

            File dir = new File(packagePath);

            //如果不存在或者 也不是目录就直接返回

            if (!dir.exists() || !dir.isDirectory()) {

                return;

            }

            //如果存在 就获取包下的所有文件 包括目录

            File[] dirfiles = dir.listFiles(new FileFilter() {

            //自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)

                  public boolean accept(File file) {

                    return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));

                  }

                });

            //循环所有文件

            for (File file : dirfiles) {

                //如果是目录 则继续扫描

                if (file.isDirectory()) {

                    findAndAddClassesInPackageByFile(packageName + "." + file.getName(),

                                          file.getAbsolutePath(),

                                          recursive,

                                          classes);

                }

                else {

                    //如果是java类文件 去掉后面的.class 只留下类名

                    String className = file.getName().substring(0, file.getName().length() - 6);

                    try {

                        //添加到集合中去

                        classes.add(Class.forName(packageName + '.' + className));

                    } catch (ClassNotFoundException e) {

                        e.printStackTrace();

                    }

                }

            }

        }


    #End If
     
    Last edited: Jun 13, 2018
  2. Erel

    Erel Administrator Staff Member Licensed User

    It will appear correctly if you add a reference to the OkHttp library. The problem is actually in the dependency list of OkHttpUtils2. It will be fixed.
     
  3. icefairy333

    icefairy333 Active Member Licensed User

    got it ,thank you
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice